diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml new file mode 100644 index 0000000..de1a994 --- /dev/null +++ b/.github/workflows/gh-pages.yml @@ -0,0 +1,57 @@ +# Sample workflow for building and deploying a Jekyll site to GitHub Pages +name: Build and Deploy GitHub Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["main"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + if: "contains(github.event.head_commit.message, '[:GHPAGES:]')" + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install additional packages + run: sudo apt-get update -y && sudo pip install -U sphinx sphinx_rtd_theme + + - name: Build documents + run: | + make docs + mkdir _site/ + cp -r docs/_build/html/* _site/ + + - name: Setup Pages + uses: actions/configure-pages@v3 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 diff --git a/.gitignore b/.gitignore index 7460f72..6b984c0 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,7 @@ go.work bin/* *.log *.out + + +_site/ +docs/_build/ diff --git a/LICENSE b/LICENSE index e69de29..261eeb9 100644 --- a/LICENSE +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile index d9d2cd3..8a37b3b 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ PKG_MANAGER ?= $(shell command -v dnf yum|head -n1) BUILDFLAGS := -mod=vendor $(BUILDFLAGS) #================================================= -# Build binary, clean, install and uninstall +# Build binary, documents #================================================= all: binary @@ -26,6 +26,11 @@ $(TARGET): $(SRC) @mkdir -p $(BIN) $(GO) build $(BUILDFLAGS) -o $(BIN)/$(TARGET) ./cmd/$(TARGET)/ +.PHONY: docs +docs: ## Generates html documents + @make -C docs + + #================================================= # Required tools installation tartgets #================================================= @@ -83,7 +88,7 @@ gofmt: ## Run gofmt .PHONY: codespell codespell: ## Run codespell @echo "running codespell" - @codespell -S ./vendor,go.mod,go.sum,./.git + @codespell -S ./vendor,go.mod,go.sum,./.git,./docs/_build #================================================= # Help menu diff --git a/README.md b/README.md index f662be7..04a9d4c 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,15 @@ This is the golang implementation of the OpenSky network's live API. The API lets you retrieve live airspace information (ADS-B and Mode S data) for research and non-commerical purposes. -A command line (`gopensky-query`) is also available to query the opensky network api. +For documentation and examples visit [Golang OpenSky Network API](https://navidys.github.io/gopensky/). -`NOTE:` there are some limitation sets for anonymous and OpenSky users, visit [OpenSky Network Rest API documentation](https://openskynetwork.github.io/opensky-api/) for more information. +A `gopensky-query` binary command line is also available to query the opensky network api. -For more information about OpenSky Network visit [OpenSky Network Website](https://opensky-network.org/). +`NOTE:` there are some limitation sets for anonymous and OpenSky users, visit following links for more information: +* [OpenSky Network Rest API documentation](https://openskynetwork.github.io/opensky-api/) +* [OpenSky Network Website](https://opensky-network.org/). -## Example -### gopensky module +## gopensky module ``` import ( @@ -43,9 +44,18 @@ func main() { } ``` -### gopensky-query cmd (json output) +## gopensky-query cmd + +### build + +``` +$ make binary +``` + +### json output + ``` -$ gopensky /bin/gopensky-query states -j +$ ./bin/gopensky-query /bin/gopensky-query states -j { "time": 1699160183, "states": [ @@ -76,9 +86,9 @@ $ gopensky /bin/gopensky-query states -j } ``` -### gopensky-query cmd (table output) +### table output ``` -$ gopensky /bin/gopensky-query states +$ ./bin/gopensky-query /bin/gopensky-query states ``` -![Screenshot](./docs/gopensky-query.png) +![Screenshot](./docs/_static/gopensky-query.png) diff --git a/cmd/gopensky-query/root.go b/cmd/gopensky-query/root.go index 6e5aa86..25b73cd 100644 --- a/cmd/gopensky-query/root.go +++ b/cmd/gopensky-query/root.go @@ -16,7 +16,7 @@ import ( var ( cmdUsername string cmdPassword string - cmdIcao24List string + cmdIcao24List []string cmdTime int64 = -1 cmdDebug = false cmdPrintJSON = false @@ -73,7 +73,7 @@ func init() { //nolint:gochecknoinits rootCmd.PersistentFlags().BoolVarP(&cmdPrintJSON, "json", "j", cmdPrintJSON, "print json output") // states command - statesCommand.Flags().StringVarP(&cmdIcao24List, "icao24", "i", "", + statesCommand.Flags().StringSliceVarP(&cmdIcao24List, "icao24", "i", cmdIcao24List, "comma separates (,) list of unique ICAO 24-bit address of the transponder in hex string representation") statesCommand.Flags().Int64VarP(&cmdTime, "time", "t", cmdTime, @@ -83,7 +83,7 @@ func init() { //nolint:gochecknoinits "request the category of aircraft ") statesCommand.Flags().Float64SliceVar(&cmdStatesBoundingBox, "box", nil, - "query a certain area defined by a bounding box of WGS84 coordinates ([lamin,lomin,lamax,lomax])") + "query a certain area defined by a bounding box of WGS84 coordinates (lamin,lomin,lamax,lomax)") rootCmd.AddCommand(statesCommand) } diff --git a/cmd/gopensky-query/states.go b/cmd/gopensky-query/states.go index dad898c..d7173d6 100644 --- a/cmd/gopensky-query/states.go +++ b/cmd/gopensky-query/states.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "os" - "strings" "text/tabwriter" "github.com/navidys/gopensky" @@ -30,16 +29,7 @@ func preStateRun(cmd *cobra.Command, args []string) error { } func runStates(cmd *cobra.Command, args []string) { - var ( - icao24List []string - boundingBoxOpts *gopensky.BoundingBoxOptions - ) - - icao24Input := strings.TrimSpace(cmdIcao24List) - - if icao24Input != "" { - icao24List = strings.Split(icao24Input, ",") - } + var boundingBoxOpts *gopensky.BoundingBoxOptions if len(cmdStatesBoundingBox) == 4 { //nolint:gomnd boundingBoxOpts = &gopensky.BoundingBoxOptions{ @@ -57,7 +47,7 @@ func runStates(cmd *cobra.Command, args []string) { return } - states, err := gopensky.GetStates(conn, cmdTime, icao24List, boundingBoxOpts, cmdStatesExtended) + states, err := gopensky.GetStates(conn, cmdTime, cmdIcao24List, boundingBoxOpts, cmdStatesExtended) if err != nil { log.Error().Msgf("%v", err) diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..5cbb4e1 --- /dev/null +++ b/doc.go @@ -0,0 +1,5 @@ +/* +This is the golang implementation of the OpenSky network's live API. +The API lets you retrieve live airspace information (ADS-B and Mode S data) for research and non-commercial purposes. +*/ +package gopensky diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..1e83189 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,22 @@ +all: html + +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) +$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) +endif + +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: html +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 0000000..b28e5f5 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,14 @@ +/* override table width restrictions */ +@media screen and (min-width: 767px) { + + .wy-table-responsive table td { + /* !important prevents the common CSS stylesheets from + overriding this as on RTD they are loaded after this stylesheet */ + white-space: normal !important; + } + + .wy-table-responsive { + overflow: visible !important; + } + + } diff --git a/docs/gopensky-query.png b/docs/_static/gopensky-query.png similarity index 100% rename from docs/gopensky-query.png rename to docs/_static/gopensky-query.png diff --git a/docs/_static/radar.png b/docs/_static/radar.png new file mode 100644 index 0000000..76e91a7 Binary files /dev/null and b/docs/_static/radar.png differ diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..6773bbb --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,251 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# + +import sys +import os +import sphinx_rtd_theme + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('../../python')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.mathjax', + 'sphinx.ext.napoleon' +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +toc_object_entries = False + +# General information about the project. +project = 'Go OpenSky Network API' +copyright = "2023, Navid Yaghoobi (navidys@fedoraproject.com)" +author = 'Navid Yaghoobi' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = "en" + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = os.path.join('_static', 'radar.png') + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'GoOpenSkyNetworkAPIdoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + +# Custom CSS e.g. for table width +def setup(app): + app.add_css_file("custom.css") diff --git a/docs/examples.rst b/docs/examples.rst new file mode 100644 index 0000000..1a38c38 --- /dev/null +++ b/docs/examples.rst @@ -0,0 +1,40 @@ +Examples +======== + +All State Vectors +-------------------- +Example for retrieving all states without authentication: + +.. code-block:: go + + import ( + "context" + "fmt" + "os" + + "github.com/navidys/gopensky" + ) + + func main() { + conn, err := gopensky.NewConnection(context.Background(), "", "") + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // retrieve all states information + statesData, err := gopensky.GetStates(conn, 0, nil, nil) + if err != nil { + fmt.Println(err) + os.Exit(2) + } + + for _, state := range statesData.States { + fmt.Printf("ICAO24: %s, Origin Country: %s, Longitude: %v, Latitude: %v \n", + state.Icao24, + state.OriginCountry, + state.Longitude, + state.Latitude, + ) + } + } diff --git a/docs/goapi_functions.rst b/docs/goapi_functions.rst new file mode 100644 index 0000000..1631207 --- /dev/null +++ b/docs/goapi_functions.rst @@ -0,0 +1,62 @@ +Go OpenSky API Functions +============================== + +.. _FUNC_CONNECTION: + +func :ref:`NewConnection ` +-------------------------------------------- + + Creates a new connection context to OpenSky Network live API server. + + + .. code-block:: go + + func NewConnection(ctx context.Context, username string, password string) (context.Context, error) + + + :Parameters: + - **ctx** (`context.Context `_) - connection context. + - **username** (string) - an OpenSky username (Anonymous connection will be use by providing empty username). + - **password** (string) - an OpenSky password for the given username. + + :Returns: context.Context, error + +.. _FUNC_GET_STATES: + +func :ref:`GetStates ` +-------------------------------------------- + + Retrieve state vectors for a given time. + + .. code-block:: go + + func GetStates(ctx context.Context, time int64, icao24 []string, bBox *BoundingBoxOptions, extended bool) (*States, error) + + + :Parameters: + - **ctx** (`context.Context `_) - connection context. + - **time** (int64) - time as Unix time stamp (seconds since epoch) or datetime. The datetime must be in UTC!. If ``time = 0`` the most recent ones are taken. + - **icao24** ([]string) - optionally retrieve only state vectors for the given ICAO24 address(es). The parameter an array of str containing multiple addresses. + - **bBox** (:ref:`*BoundingBoxOptions`) - optionally retrieve state vectors within a bounding box. Use :ref:`NewBoundingBox` function to create a new one. + - **extended** (bool) - set to ``true`` to request the category of aircraft + + :Returns: :ref:`*States`, error + +.. _BBOX_FUNC: + +func :ref:`NewBoundingBox ` +-------------------------------------------- + + Creates a new bounding (min_latitude, max_latitude, min_longitude, max_longitude) box option. + + .. code-block:: go + + func NewBoundingBox (lamin float64, lomin float64, lamax float64, lomax float64) *BoundingBoxOptions + + :Parameters: + - **lamin** (float64) - lower bound for the latitude in WGS84 decimal degrees. + - **lomin** (float64) - lower bound for the longitude in in WGS84 decimal degrees. + - **lamax** (float64) - upper bound for the latitude in WGS84 decimal degrees. + - **lomax** (float64) - upper bound for the longitude in in WGS84 decimal degrees. + + :Returns: :ref:`*BoundingBoxOptions` diff --git a/docs/goapi_types.rst b/docs/goapi_types.rst new file mode 100644 index 0000000..8d46bb5 --- /dev/null +++ b/docs/goapi_types.rst @@ -0,0 +1,126 @@ +Go OpenSky API Types +======================== + +.. _TYPE_STATES: + +type :ref:`States ` +-------------------------------------------- + +.. code-block:: go + + type States struct { + // The time which the state vectors in this response are associated with. + // All vectors represent the state of a vehicle with the interval. + Time int64 `json:"time"` + + // The state vectors. + // States []StateVector `json:"states"` + States []StateVector `json:"states"` + } + +.. _TYPE_STATE_VECTOR: + +type :ref:`StateVector ` +-------------------------------------------- + +.. code-block:: go + + type StateVector struct { + // Unique ICAO 24-bit address of the transponder in hex string representation. + Icao24 string `json:"icao24"` + + // Callsign of the vehicle (8 chars). Can be null if no callsign has been received. + Callsign *string `json:"callsign"` + + // Country name inferred from the ICAO 24-bit address. + OriginCountry string `json:"origin_country"` + + // Unix timestamp (seconds) for the last position update. + // Can be null if no position report was received by OpenSky within the past 15s. + TimePosition *int64 `json:"time_position"` + + // Unix timestamp (seconds) for the last update in general. + // This field is updated for any new, valid message received from the transponder. + LastContact int64 `json:"last_contact"` + + // WGS-84 longitude in decimal degrees. Can be null. + Longitude *float64 `json:"longitude"` + + // WGS-84 latitude in decimal degrees. Can be null. + Latitude *float64 `json:"latitude"` + + // Barometric altitude in meters. Can be null. + BaroAltitude *float64 `json:"baro_altitude"` + + // Boolean value which indicates if the position was retrieved from a surface position report. + OnGround bool `json:"on_ground"` + + // Velocity over ground in m/s. Can be null. + Velocity *float64 `json:"velocity"` + + // True track in decimal degrees clockwise from north (north=0°). Can be null. + TrueTrack *float64 `json:"true_track"` + + // Vertical rate in m/s. + // A positive value indicates that the airplane is climbing, a negative value indicates that it descends. + // Can be null. + VerticalRate *float64 `json:"vertical_rate"` + + // IDs of the receivers which contributed to this state vector. + // Is null if no filtering for sensor was used in the request. + Sensors []int `json:"sensors"` + + // Geometric altitude in meters. Can be null. + GeoAltitude *float64 `json:"geo_altitude"` + + // The transponder code aka Squawk. Can be null. + Squawk *string `json:"squawk"` + + // Whether flight status indicates special purpose indicator. + Spi bool `json:"spi"` + + // Origin of this state’s position. + // 0 = ADS-B + // 1 = ASTERIX + // 2 = MLAT + // 3 = FLARM + PositionSource int `json:"position_source"` + + // Aircraft category. + // 0 = No information at all + // 1 = No ADS-B Emitter Category Information + // 2 = Light (< 15500 lbs) + // 3 = Small (15500 to 75000 lbs) + // 4 = Large (75000 to 300000 lbs) + // 5 = High Vortex Large (aircraft such as B-757) + // 6 = Heavy (> 300000 lbs) + // 7 = High Performance (> 5g acceleration and 400 kts) + // 8 = Rotorcraft + // 9 = Glider / sailplane + // 10 = Lighter-than-air + // 11 = Parachutist / Skydiver + // 12 = Ultralight / hang-glider / paraglider + // 13 = Reserved + // 14 = Unmanned Aerial Vehicle + // 15 = Space / Trans-atmospheric vehicle + // 16 = Surface Vehicle – Emergency Vehicle + // 17 = Surface Vehicle – Service Vehicle + // 18 = Point Obstacle (includes tethered balloons) + // 19 = Cluster Obstacle + // 20 = Line Obstacle + Category int `json:"category"` + } + +.. _TYPE_BBOX_OPTIONS: + +type :ref:`BoundingBoxOption ` +------------------------------------------------- + +.. code-block:: go + + type BoundingBoxOptions struct { + Lamin float64 // Lower bound for the latitude in decimal degrees. + Lomin float64 // lower bound for the longitude in decimal degrees. + Lamax float64 // upper bound for the latitude in decimal degrees. + Lomax float64 // upper bound for the longitude in decimal degrees. + } diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..791810a --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,42 @@ +Go OpenSky Network API documentation +==================================== + +**gopensky** is the Go implementation of the OpenSky network's live API. +It lets you retrieve live airspace information (ADS-B and Mode S data) for research and non-commerical purposes. + + +There are some limitation sets for anonymous and OpenSky users, visit following links for more information: + + * `OpenSky Network Rest API documentation `_ + * `OpenSky Network Website `_ + +.. warning:: + + This project is under active development. + +Installation +-------------- + +Use ``go get`` to install the latest version of the library: + +.. code-block:: bash + + $ go get github.com/navidys/gopensky + +Next, include gopensky in you application: + +.. code-block:: go + + import "github.com/navidys/gopensky" + + +Further Reading +--------------- + +.. toctree:: + :maxdepth: 1 + + Introduction + Go API Functions + Go API Types + Examples diff --git a/states.go b/states.go index 2e30973..e0be714 100644 --- a/states.go +++ b/states.go @@ -55,16 +55,6 @@ func GetStates(ctx context.Context, time int64, icao24 []string, return &states, nil } -// NewBoundingBox returns new bounding box options for states information gathering. -func NewBoundingBox(lamin float64, lomin float64, lamax float64, lomax float64) *BoundingBoxOptions { - return &BoundingBoxOptions{ - Lamin: lamin, - Lomin: lomin, - Lamax: lamax, - Lomax: lomax, - } -} - func getStateRequestParams(time int64, icao24 []string, bBox *BoundingBoxOptions, extended bool) url.Values { requestParams := make(url.Values) if time >= 0 { diff --git a/types_state.go b/types_state.go index c598ce1..0b39e39 100644 --- a/types_state.go +++ b/types_state.go @@ -165,3 +165,13 @@ type BoundingBoxOptions struct { // upper bound for the longitude in decimal degrees. Lomax float64 } + +// NewBoundingBox returns new bounding box options for states information gathering. +func NewBoundingBox(lamin float64, lomin float64, lamax float64, lomax float64) *BoundingBoxOptions { + return &BoundingBoxOptions{ + Lamin: lamin, + Lomin: lomin, + Lamax: lamax, + Lomax: lomax, + } +}