Skip to content

Commit

Permalink
feat: small refactor and more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
brpaz committed Jun 28, 2020
1 parent c029b52 commit 2b460ab
Show file tree
Hide file tree
Showing 18 changed files with 317 additions and 66 deletions.
32 changes: 30 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,25 +20,34 @@ This extension allows to easily search on popular documentation websites, that i
The following documentation sites are included by default in this extension:

- Apollo GraphQL
- Babel
- Cypress
- Echo Framework
- Echo
- Eslint
- Gatsby
- GitLab
- GORM
- Grafana
- GraphQL
- Gridsome
- Jest
- Laravel
- NuxtJS
- Parcel
- Prettier
- Prometheus
- React
- Scala
- Tailwind
- Typescript
- VueJS
- Vue
- Vuepress
- Vuetify
- Vuex
- Vue-Router
- Webpack


## Usage

![demo](demo.gif)
Expand All @@ -57,6 +66,17 @@ Open ulauncher preferences window -> extensions -> add extension and paste the f
https://github.com/brpaz/ulauncher-docsearch
```

## Usage

Open Ulauncher and type ```docs```. A list of available documentation sites will appear. Select one and type your search keyword to search on that website.

Optionally some documentation also supports a custom keyword, to trigger it directly without having to type ```docs``` before.

For example, for Vue documentation, you can just type ```vue <query>```.

You can see the supported keywords in [manifest.json](manifest.json) file.


## Development

```
Expand All @@ -72,13 +92,21 @@ To see your changes, stop ulauncher and run it from the command line with: `ulau

All contributions are welcome.

If you want to add new documentation, you can either do a PR so other users can benefit with it or adding it locally.

Please see the following guide to know how:

* [Add new documentation](docs/add-new-doc.md)


## Show your support

<a href="https://www.buymeacoffee.com/Z1Bu6asGV" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png" alt="Buy Me A Coffee" style="height: 41px !important;width: 174px !important;box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;-webkit-box-shadow: 0px 3px 2px 0px rgba(190, 190, 190, 0.5) !important;" ></a>

## Credits

This project would never be possible without the awesome folks at [Algolia](https://www.algolia.com/) who build this search engine and all the websites that implemented it.

## License

Copywright @ 2019 [Bruno Paz](https://github.com/brpaz)
Expand Down
99 changes: 99 additions & 0 deletions data/docsets.json
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,24 @@
"algolia_api_key": "259d4615e283a1bbaa3313b4eff7881c",
"url": "https://vuetifyjs.com/en/getting-started/quick-start"
},
"vuex": {
"name": "Vuex",
"description": "Vuex is a state management pattern + library for Vue.js applications.",
"icon": "images/docs/vuex.png",
"algolia_index": "vuex",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "97f135e4b5f5487fb53f0f2dae8db59d",
"url": "https://vuex.vuejs.org/"
},
"vue-router": {
"name": "Vue Router",
"description": "Vue Router is the official router for Vue.js",
"icon": "images/docs/vue.png",
"algolia_index": "vue-router",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "f854bb46d3de7eeb921a3b9173bd0d4c",
"url": "https://router.vuejs.org/"
},
"parcel": {
"name": "parcel",
"description": "Parcel is a web application bundler, differentiated by its developer experience.",
Expand All @@ -169,5 +187,86 @@
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "8b6be780425a72d1a1683abea2636778",
"url": "https://vuetifyjs.com/en/getting-started/quick-start"
},
"laravel": {
"name": "Laravel",
"description": "The PHP Framework for Web Artisans",
"icon": "images/docs/laravel.png",
"algolia_index": "laravel",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "7dc4fe97e150304d1bf34f5043f178c4",
"url": "https://laravel.com/docs/7.x/"
},
"nestjs": {
"name": "NestJS",
"description": "A progressive Node.js framework for building efficient, reliable and scalable server-side applications",
"icon": "images/docs/nestjs.png",
"algolia_index": "nestjs",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "9ea53de1a6911255834352bbbe4d3417",
"url": "https://docs.nestjs.com/"
},
"bootstrap": {
"name": "Bootstrap",
"description": "Build fast, responsive sites with Bootstrap",
"icon": "images/docs/bootstrap.png",
"algolia_index": "bootstrap",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "5990ad008512000bba2cf951ccf0332f",
"url": "https://getbootstrap.com/docs/4.5/getting-started/introduction/"
},
"netlify": {
"name": "Netlify",
"description": "",
"icon": "images/docs/netlify.png",
"algolia_index": "docs-manual",
"algolia_application_id": "4RTNPM1QF9",
"algolia_api_key": "260466eb2466a36278b2fdbcc56ad7ba",
"url": "https://docs.netlify.com/"
},
"babel": {
"name": "Babel",
"description": "Use next generation JavaScript, today.",
"icon": "images/docs/babeljs.png",
"algolia_index": "babeljs",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "d42906b043c5422ea07b44fd49c40a0d",
"url": "https://babeljs.io/docs/en/"
},
"gorm": {
"name": "Gorm",
"description": "The fantastic ORM library for Golang",
"icon": "images/docs/gorm.png",
"algolia_index": "gorm",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "442683d88a109de42c6d01bb0c7c4cec",
"url": "https://gorm.io/"
},
"grafana": {
"name": "Grafana",
"description": "The fantastic ORM library for Golang",
"icon": "images/docs/grafana.png",
"algolia_index": "grafana",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "0bd2bd6939038c5ce2c9395732dcf040",
"url": "https://grafana.com/docs/grafana/latest/"
},
"prometheus": {
"name": "Prometheus",
"description": "Power your metrics and alerting with a leading open-source monitoring solution.",
"icon": "images/docs/prometheus.png",
"algolia_index": "prometheus",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "48ac0b7924908a1fd40b1cb18b402ba1",
"url": "https://prometheus.io/docs/"
},
"prettier": {
"name": "Prettier",
"description": "An opinionated code formatter",
"icon": "images/docs/prettier.png",
"algolia_index": "prettier",
"algolia_application_id": "BH4D9OD16A",
"algolia_api_key": "9fcdb2a62af4c47cc5eecf3d5a747818",
"url": "https://prettier.io/docs/en"
}
}
12 changes: 11 additions & 1 deletion docs/add-new-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,20 @@ It´s pretty easy to add new documentation to this extension.

The only requirement is that the Documentation site must use [Algolia DocSearch](https://community.algolia.com/docsearch/) as their search engine. You can check all availalbe sites [here](https://github.com/algolia/docsearch-configs).

The first step is to add an entry to the [data/docsets.json](../data/docsets.json) file.
The first step is to add an entry to the docsets json file.

The "algolia_index", "algolia_application_id" and "algolia_api_key" properties can be found by inspecting the search request of the original site. For example for VueJS documentation, do a search and look for the following in the "Netowrk tab" of your Browser

![add docs](add-docs.png)

You also need to add an icon to the **icons/docs** folder, whose path should match the one configured in "docset.json" file.

## Add local documentation

Besides the default `docsets.json`, this extension also looks for the file `~/.config/ulauncher/ext_preferences/docsearch/docsets.json`. You can use this method if you dont want to share your documentation.

The file is exactly the same structure as the default.

It doesnt exist by default, you have to create it manually.

The icon can be placed anywhere in ```~/.config/ulauncher/ext_preferences/docsearch``` directory. You must add the relative path from this directory to your `docsets.json` file.
Empty file added docsearch/__init__.py
Empty file.
58 changes: 53 additions & 5 deletions docs.py → docsearch/searcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,48 @@

LOGGING = logging.getLogger(__name__)

DOCSETS_FILE_PATH = os.path.join(os.path.dirname(__file__), 'data',
DOCSETS_FILE_PATH = os.path.join(os.path.dirname(__file__), '..', 'data',
'docsets.json')

USER_DOCSETS_PATH = os.path.join(os.path.expanduser("~"), ".config",
"ulauncher", "ext_preferences", "docsearch")

class DocSearch:

class Searcher:
""" Searches Documentation On DocSearch based applications """
def __init__(self):
""" Class constructor """
self.docsets = {}

self.load_default_docsets()
self.load_user_docsets()

def load_default_docsets(self):
""" Loads default docsets into memory """
with open(DOCSETS_FILE_PATH, 'r') as data:
self.docsets = json.load(data)

def load_user_docsets(self):
""" Loads custom user docsets """
if not os.path.isdir(USER_DOCSETS_PATH):
return

docsets_file = os.path.join(USER_DOCSETS_PATH, "docsets.json")

if not os.path.isfile(docsets_file):
return

with open(docsets_file, 'r') as data:
user_docsets = json.load(data)

for key, docset in user_docsets.items():
icon = os.path.join(USER_DOCSETS_PATH, docset["icon"])
if not os.path.isfile(icon):
icon = "images/icon.png"
user_docsets[key]["icon"] = icon

self.docsets.update(user_docsets)

def get_available_docs(self, filter_term):
""" Returns a list of available docs """
docs = []
Expand All @@ -49,8 +78,7 @@ def has_docset(self, key):

def get_docset(self, key):
""" Returns the details from a docset with the specified key passed as argument """

if key in self.docsets.keys():
if key in self.docsets:
return self.docsets[key]

return None
Expand All @@ -66,7 +94,9 @@ def search(self, docset, term):
docset['algolia_api_key'])

index = algolia_client.init_index(docset['algolia_index'])
search_results = index.search(term)

search_results = index.search(
term, self.get_search_request_options_for_docset(docset))

if not search_results['hits']:
return []
Expand Down Expand Up @@ -95,3 +125,21 @@ def parse_item_description(self, hit):

# The last element found will be the description and the previous one the title.
return res[-1], ' -> '.join(res[:-1])

def get_search_request_options_for_docset(self, docset):
""" Allow to specify custom search options for a specific docset """
opts = {}

if docset["name"] == 'Nuxt':
opts = {"facetFilters": ["tags:en"]}

if docset["name"] == "Bootstrap":
opts = {"facetFilters": ["version:4.5"]}

if docset["name"] == "Vuex":
opts = {"facetFilters": ["lang:en-US"]}

if docset["name"] == "Vue Router":
opts = {"facetFilters": ["lang:en-US"]}

return opts
Binary file added images/docs/babeljs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/docs/bootstrap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/docs/gorm.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/docs/grafana.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/docs/laravel.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/docs/nestjs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/docs/netlify.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/docs/prettier.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/docs/prometheus.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/docs/vuex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified images/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2b460ab

Please sign in to comment.