├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── contributing.md ├── curated-lists.go ├── learn-anything.go ├── license ├── main.go ├── modd.conf ├── readme.md ├── update.go └── workflow ├── icon.png ├── icons └── update-available.png ├── info.plist ├── lists.md └── maps.json /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug 🐞 3 | about: Something isn't working as expected? 4 | labels: bug 5 | --- 6 | 7 | ### Bug 🐞 8 | 9 | 10 | 11 | 12 | ### Steps to Reproduce: 13 | 14 | 1. 15 | 2. 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature ✨ 3 | about: Suggest new idea for the project 4 | labels: enhancement 5 | --- 6 | 7 | ### Feature ✨ 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 🤔 3 | about: Usage question or discussion 4 | labels: question 5 | --- 6 | 7 | ### Question 🤔 8 | 9 | 10 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Summary 2 | 3 | 4 | 5 | 6 | ### Changes 7 | 8 | - 9 | 10 | 11 | ### Notes 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | workflow/alfred-learn-anything 2 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for taking the time to contribute! ♥️ You can: 4 | 5 | - Submit [bug reports or feature requests](../../issues/new/choose). Contribute to discussions. Fix [open issues](../../issues). 6 | - Improve docs, the code and more! Any idea is welcome. 7 | 8 | ## Run project 9 | 10 | The workflow is written in [Go](https://golang.org/) and uses [AwGo](https://github.com/deanishe/awgo) library for all Alfred related things. 11 | 12 | It uses [modd](https://github.com/cortesi/modd) and [Alfred command](https://godoc.org/github.com/jason0x43/go-alfred/alfred) to ease its development. 13 | 14 | 1. Clone repo 15 | 2. Run `alfred link` (makes symbolic link of [`workflow`](workflow) directory) 16 | 3. Run `modd` (starts a process that automatically builds the workflow with `alfred build` on any changes you make to `.go` files, this builds and places a binary inside [`workflow`](workflow) directory.) 17 | 4. Make changes to code or modify Alfred objects to do what you want! Open debugger in Alfred or run the workflow with `workflow:log` passed in as argument to see the logs Alfred produces. 18 | 19 | ![](https://i.imgur.com/FFYOecx.png) 20 | -------------------------------------------------------------------------------- /curated-lists.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "io/ioutil" 6 | "log" 7 | "net/http" 8 | "regexp" 9 | "strings" 10 | ) 11 | 12 | // downloadCuratedLists downloads curated lists from GitHub. 13 | func downloadCuratedLists() { 14 | resp, err := http.Get("https://raw.githubusercontent.com/learn-anything/curated-lists/master/readme.md") 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | defer resp.Body.Close() 19 | // body, err := ioutil.ReadAll(resp.Body) 20 | // TODO: add it to cache 21 | // ioutil.WriteFile("lists.md", body, 0600) 22 | } 23 | 24 | // doSearchLists searches curated lists. 25 | func doSearchLists() error { 26 | showUpdateStatus() 27 | 28 | log.Printf("query=%s", query) 29 | 30 | // TODO: where is cache placed? 31 | parseList("lists.md") 32 | 33 | if query != "" { 34 | wf.Filter(query) 35 | } 36 | 37 | wf.WarnEmpty("No matching items", "Try a different query?") 38 | wf.SendFeedback() 39 | 40 | return nil 41 | } 42 | 43 | // parseList parses a markdown list for links. 44 | func parseList(file string) { 45 | bytes, _ := ioutil.ReadFile(file) 46 | 47 | // Regex to extract markdown links 48 | re := regexp.MustCompile(`\[([^\]]*)\]\(([^)]*)\)`) 49 | 50 | // Read string line by line and apply regex 51 | scanner := bufio.NewScanner(strings.NewReader(string(bytes))) 52 | for scanner.Scan() { 53 | matches := re.FindAllStringSubmatch(scanner.Text(), -1) 54 | wf.NewItem(matches[0][1]).Arg(matches[0][2]).Valid(true).UID(matches[0][1]) 55 | } 56 | } 57 | 58 | func readList(listName string) { 59 | 60 | } 61 | -------------------------------------------------------------------------------- /learn-anything.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "log" 7 | "os" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | // Topic is Learn Anything topic. 13 | type Topic struct { 14 | ID int `json:"mapID"` 15 | Key string `json:"key"` 16 | } 17 | 18 | // doSearchTopics searches all Learn Anything topics. 19 | func doSearchTopics() error { 20 | showUpdateStatus() 21 | log.Printf("query=%s", query) 22 | 23 | m, err := loadValues("maps.json") 24 | if err != nil { 25 | log.Fatal(err) 26 | } 27 | for k, v := range m { 28 | // log.Printf(strconv.Itoa(k)) 29 | // log.Printf(v) 30 | wf.NewItem(strings.Title(string(v[0])) + v[1:]).Arg(strconv.Itoa(k)).Valid(true).UID(v) 31 | } 32 | 33 | if query != "" { 34 | wf.Filter(query) 35 | } 36 | 37 | wf.WarnEmpty("No matching items", "Try a different query?") 38 | wf.SendFeedback() 39 | return nil 40 | } 41 | 42 | // loadVaules returns ID's and keys from read JSON file. 43 | func loadValues(fileName string) (map[int]string, error) { 44 | file, err := os.Open(fileName) 45 | m := make(map[int]string) 46 | if err != nil { 47 | log.Fatal(err) 48 | } 49 | dec := json.NewDecoder(file) 50 | for { 51 | var ret Topic 52 | err := dec.Decode(&ret) 53 | if err != nil { 54 | if err == io.EOF { 55 | break 56 | } 57 | log.Fatal(err) 58 | return m, err 59 | } 60 | m[ret.ID] = ret.Key 61 | } 62 | return m, nil 63 | } 64 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Nikita (nikiv.dev) 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 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/deanishe/awgo" 7 | "github.com/deanishe/awgo/update" 8 | "gopkg.in/alecthomas/kingpin.v2" 9 | ) 10 | 11 | // Defaults for Kingpin flags 12 | const ( 13 | defaultMaxResults = "100" 14 | ) 15 | 16 | // Icons 17 | var ( 18 | IconDefault = &aw.Icon{Value: "icon.png"} 19 | IconUpdate = &aw.Icon{Value: "icons/update-available.png"} 20 | ) 21 | 22 | var ( 23 | // Kingpin and script options 24 | app *kingpin.Application 25 | 26 | // Application commands 27 | searchTopicsCmd *kingpin.CmdClause 28 | searchListsCmd *kingpin.CmdClause 29 | updateCmd *kingpin.CmdClause 30 | testCmd *kingpin.CmdClause 31 | 32 | // Script options (populated by Kingpin application) 33 | query string 34 | 35 | repo = "nikitavoloboev/alfred-learn-anything" 36 | 37 | // Workflow stuff 38 | wf *aw.Workflow 39 | ) 40 | 41 | // Sets up kingpin commands 42 | func init() { 43 | wf = aw.New(update.GitHub(repo), aw.HelpURL(repo+"/issues")) 44 | app = kingpin.New("learn anything", "Search Learn Anything.") 45 | 46 | updateCmd = app.Command("update", "Check for new version.") 47 | 48 | searchTopicsCmd = app.Command("topics", "Search Learn Anything topics.") 49 | 50 | searchListsCmd = app.Command("lists", "Search curated lists.") 51 | 52 | for _, cmd := range []*kingpin.CmdClause{ 53 | searchTopicsCmd, searchListsCmd, 54 | } { 55 | cmd.Flag("query", "Search query.").Short('q').StringVar(&query) 56 | } 57 | } 58 | 59 | func run() { 60 | var err error 61 | 62 | cmd, err := app.Parse(wf.Args()) 63 | if err != nil { 64 | wf.FatalError(err) 65 | } 66 | 67 | switch cmd { 68 | case searchTopicsCmd.FullCommand(): 69 | err = doSearchTopics() 70 | case searchListsCmd.FullCommand(): 71 | err = doSearchLists() 72 | case updateCmd.FullCommand(): 73 | err = doUpdate() 74 | default: 75 | err = fmt.Errorf("Uknown command: %s", cmd) 76 | } 77 | 78 | // Check for update 79 | if err == nil && cmd != updateCmd.FullCommand() { 80 | err = checkForUpdate() 81 | } 82 | 83 | if err != nil { 84 | wf.FatalError(err) 85 | } 86 | } 87 | 88 | func doTest() error { 89 | return nil 90 | } 91 | 92 | func main() { 93 | wf.Run(run) 94 | } 95 | -------------------------------------------------------------------------------- /modd.conf: -------------------------------------------------------------------------------- 1 | **/*.go { 2 | prep: alfred build 3 | } 4 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Alfred Learn Anything 2 | 3 | > [Alfred](https://www.alfredapp.com/) workflow to search [Learn Anything](https://learn-anything.xyz/) 4 | 5 | img 6 | 7 | The workflow lets you search through all the 2000+ topics found on [Learn Anything](https://learn-anything.xyz/). 8 | 9 | And it lets you search through all the [curated lists](https://github.com/learn-anything/curated-lists). 10 | 11 | ## Install 12 | 13 | Download workflow from [GitHub releases](../../releases/latest). 14 | 15 | See [here](https://github.com/deanishe/awgo/wiki/Catalina) for instructions on fixing permissions in macOS refusing to run Go binary. 16 | 17 | ## Contribute 18 | 19 | Always open to useful ideas or fixes in form of issues or PRs. 20 | 21 | Can [open new issue](../../issues/new/choose) (search [existing issues](../../issues) first) or [start discussion](../../discussions). 22 | 23 | It's okay to submit draft PR as you can get help along the way to make it merge ready. 24 | 25 | Join [Discord](https://discord.com/invite/TVafwaD23d) for more indepth discussions on this repo and [others](https://github.com/nikitavoloboev#src). 26 | 27 | ### 🖤 28 | 29 | [Support on GitHub](https://github.com/sponsors/nikitavoloboev) or look into [other projects](https://nikiv.dev/projects). 30 | 31 | [![Discord](https://img.shields.io/badge/Discord-100000?style=flat&logo=discord&logoColor=white&labelColor=black&color=black)](https://discord.com/invite/TVafwaD23d) [![X](https://img.shields.io/badge/nikitavoloboev-100000?logo=X&color=black)](https://twitter.com/nikitavoloboev) [![nikiv.dev](https://img.shields.io/badge/nikiv.dev-black)](https://nikiv.dev) 32 | -------------------------------------------------------------------------------- /update.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "os/exec" 7 | 8 | aw "github.com/deanishe/awgo" 9 | ) 10 | 11 | // doUpdate checks for a newer version of the workflow. 12 | func doUpdate() error { 13 | log.Println("Checking for update...") 14 | return wf.CheckForUpdate() 15 | } 16 | 17 | // checkForUpdate runs "./alsf update" in the background if an update check is due. 18 | func checkForUpdate() error { 19 | if !wf.UpdateCheckDue() || aw.IsRunning("update") { 20 | return nil 21 | } 22 | cmd := exec.Command(os.Args[0], "update") 23 | return aw.RunInBackground("update", cmd) 24 | } 25 | 26 | // showUpdateStatus adds an "update available!" message to Script Filters if an update is available 27 | // and query is empty. 28 | func showUpdateStatus() { 29 | if query != "" { 30 | return 31 | } 32 | 33 | if wf.UpdateAvailable() { 34 | wf.Configure(aw.SuppressUIDs(true)) 35 | log.Println("Update available!") 36 | wf.NewItem("An update is available!"). 37 | Subtitle("⇥ or ↩ to install update"). 38 | Valid(false). 39 | Autocomplete("workflow:update"). 40 | Icon(IconUpdate) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /workflow/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikitavoloboev/alfred-learn-anything/418281e986fc177e8921515ff06bdb9b669c5370/workflow/icon.png -------------------------------------------------------------------------------- /workflow/icons/update-available.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nikitavoloboev/alfred-learn-anything/418281e986fc177e8921515ff06bdb9b669c5370/workflow/icons/update-available.png -------------------------------------------------------------------------------- /workflow/info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | bundleid 6 | nikivi.learn.anything 7 | category 8 | Mine 9 | connections 10 | 11 | 05C2CDF4-B8F6-48B5-9DCC-75AC001E1500 12 | 13 | 14 | destinationuid 15 | 3E3F5B1F-5EA1-4271-952C-1B1897B454DE 16 | modifiers 17 | 0 18 | modifiersubtext 19 | 20 | vitoclose 21 | 22 | 23 | 24 | 0AFED35D-0B15-4070-A6C4-E762A091EC86 25 | 26 | 27 | destinationuid 28 | 60D56C11-AA30-44D1-82E2-67C0A0B87073 29 | modifiers 30 | 0 31 | modifiersubtext 32 | 33 | vitoclose 34 | 35 | 36 | 37 | 2C61650C-01F2-4BC7-AAE0-8C31508A2833 38 | 39 | 40 | destinationuid 41 | 3E8C3225-79D1-43C3-A4E3-583E4B6B152F 42 | modifiers 43 | 0 44 | modifiersubtext 45 | 46 | vitoclose 47 | 48 | 49 | 50 | 3E3F5B1F-5EA1-4271-952C-1B1897B454DE 51 | 52 | 53 | destinationuid 54 | 790627A4-87DA-408A-BC71-90FA3D9CDF36 55 | modifiers 56 | 0 57 | modifiersubtext 58 | 59 | vitoclose 60 | 61 | 62 | 63 | 3E8C3225-79D1-43C3-A4E3-583E4B6B152F 64 | 65 | 66 | destinationuid 67 | 4F774142-7D29-4E25-8B08-5CCEAA253E53 68 | modifiers 69 | 0 70 | modifiersubtext 71 | 72 | vitoclose 73 | 74 | 75 | 76 | 4F774142-7D29-4E25-8B08-5CCEAA253E53 77 | 78 | 79 | destinationuid 80 | C7FE3DF8-D5CD-4468-8CE0-BB050EF48F17 81 | modifiers 82 | 0 83 | modifiersubtext 84 | 85 | vitoclose 86 | 87 | 88 | 89 | destinationuid 90 | 0AFED35D-0B15-4070-A6C4-E762A091EC86 91 | modifiers 92 | 1048576 93 | modifiersubtext 94 | View contributing guidelines 95 | vitoclose 96 | 97 | 98 | 99 | destinationuid 100 | 72B1AA05-3281-415B-9252-9036D705817A 101 | modifiers 102 | 262144 103 | modifiersubtext 104 | Edit list 105 | vitoclose 106 | 107 | 108 | 109 | 60D56C11-AA30-44D1-82E2-67C0A0B87073 110 | 111 | 112 | destinationuid 113 | 62FC303E-01BA-430E-BC35-C7365486A097 114 | modifiers 115 | 0 116 | modifiersubtext 117 | 118 | vitoclose 119 | 120 | 121 | 122 | 72B1AA05-3281-415B-9252-9036D705817A 123 | 124 | 125 | destinationuid 126 | AEABCB9D-9232-43D3-8640-84C9451203E0 127 | modifiers 128 | 0 129 | modifiersubtext 130 | 131 | vitoclose 132 | 133 | 134 | 135 | 790627A4-87DA-408A-BC71-90FA3D9CDF36 136 | 137 | 138 | destinationuid 139 | 238CAD6B-EF29-4AF9-8A6D-A45407BBC0CE 140 | modifiers 141 | 0 142 | modifiersubtext 143 | 144 | vitoclose 145 | 146 | 147 | 148 | AEABCB9D-9232-43D3-8640-84C9451203E0 149 | 150 | 151 | destinationuid 152 | A2A341B0-792A-43F0-A4F7-7F2755274850 153 | modifiers 154 | 0 155 | modifiersubtext 156 | 157 | vitoclose 158 | 159 | 160 | 161 | 162 | createdby 163 | Nikita Voloboev 164 | description 165 | Search Learn Anything 166 | disabled 167 | 168 | name 169 | Learn Anything 170 | objects 171 | 172 | 173 | config 174 | 175 | alfredfiltersresults 176 | 177 | alfredfiltersresultsmatchmode 178 | 0 179 | argumenttreatemptyqueryasnil 180 | 181 | argumenttrimmode 182 | 0 183 | argumenttype 184 | 1 185 | escaping 186 | 102 187 | keyword 188 | learn 189 | queuedelaycustom 190 | 3 191 | queuedelayimmediatelyinitially 192 | 193 | queuedelaymode 194 | 0 195 | queuemode 196 | 1 197 | runningsubtext 198 | Loading... 199 | script 200 | ./alfred-learn-anything topics -q "$1" 201 | scriptargtype 202 | 1 203 | scriptfile 204 | 205 | subtext 206 | Search topics 207 | title 208 | Learn Anything 209 | type 210 | 0 211 | withspace 212 | 213 | 214 | type 215 | alfred.workflow.input.scriptfilter 216 | uid 217 | 790627A4-87DA-408A-BC71-90FA3D9CDF36 218 | version 219 | 3 220 | 221 | 222 | config 223 | 224 | browser 225 | 226 | spaces 227 | 228 | url 229 | https://learn-anything.xyz/{query} 230 | utf8 231 | 232 | 233 | type 234 | alfred.workflow.action.openurl 235 | uid 236 | 238CAD6B-EF29-4AF9-8A6D-A45407BBC0CE 237 | version 238 | 1 239 | 240 | 241 | config 242 | 243 | triggerid 244 | search learn anything 245 | 246 | type 247 | alfred.workflow.trigger.external 248 | uid 249 | 05C2CDF4-B8F6-48B5-9DCC-75AC001E1500 250 | version 251 | 1 252 | 253 | 254 | config 255 | 256 | json 257 | { 258 | "alfredworkflow" : { 259 | "arg" : "{query}", 260 | "config" : { 261 | "title" : "", 262 | "runningsubtext" : "", 263 | "subtext" : "" 264 | }, 265 | "variables" : { 266 | } 267 | } 268 | } 269 | 270 | type 271 | alfred.workflow.utility.json 272 | uid 273 | 3E3F5B1F-5EA1-4271-952C-1B1897B454DE 274 | version 275 | 1 276 | 277 | 278 | config 279 | 280 | browser 281 | 282 | spaces 283 | 284 | url 285 | {query} 286 | utf8 287 | 288 | 289 | type 290 | alfred.workflow.action.openurl 291 | uid 292 | C7FE3DF8-D5CD-4468-8CE0-BB050EF48F17 293 | version 294 | 1 295 | 296 | 297 | config 298 | 299 | triggerid 300 | search lists 301 | 302 | type 303 | alfred.workflow.trigger.external 304 | uid 305 | 2C61650C-01F2-4BC7-AAE0-8C31508A2833 306 | version 307 | 1 308 | 309 | 310 | config 311 | 312 | alfredfiltersresults 313 | 314 | alfredfiltersresultsmatchmode 315 | 0 316 | argumenttreatemptyqueryasnil 317 | 318 | argumenttrimmode 319 | 0 320 | argumenttype 321 | 1 322 | escaping 323 | 102 324 | keyword 325 | list 326 | queuedelaycustom 327 | 3 328 | queuedelayimmediatelyinitially 329 | 330 | queuedelaymode 331 | 0 332 | queuemode 333 | 1 334 | runningsubtext 335 | Loading... 336 | script 337 | ./alfred-learn-anything lists -q "$1" 338 | scriptargtype 339 | 1 340 | scriptfile 341 | 342 | subtext 343 | Search curated lists 344 | title 345 | Curated lists 346 | type 347 | 0 348 | withspace 349 | 350 | 351 | type 352 | alfred.workflow.input.scriptfilter 353 | uid 354 | 4F774142-7D29-4E25-8B08-5CCEAA253E53 355 | version 356 | 3 357 | 358 | 359 | config 360 | 361 | json 362 | { 363 | "alfredworkflow" : { 364 | "arg" : "{query}", 365 | "config" : { 366 | "title" : "", 367 | "runningsubtext" : "", 368 | "subtext" : "" 369 | }, 370 | "variables" : { 371 | } 372 | } 373 | } 374 | 375 | type 376 | alfred.workflow.utility.json 377 | uid 378 | 3E8C3225-79D1-43C3-A4E3-583E4B6B152F 379 | version 380 | 1 381 | 382 | 383 | config 384 | 385 | browser 386 | 387 | spaces 388 | 389 | url 390 | {var:link} 391 | utf8 392 | 393 | 394 | type 395 | alfred.workflow.action.openurl 396 | uid 397 | 62FC303E-01BA-430E-BC35-C7365486A097 398 | version 399 | 1 400 | 401 | 402 | config 403 | 404 | concurrently 405 | 406 | escaping 407 | 102 408 | script 409 | query=$1 410 | 411 | echo -n "${query//}" 412 | scriptargtype 413 | 1 414 | scriptfile 415 | 416 | type 417 | 0 418 | 419 | type 420 | alfred.workflow.action.script 421 | uid 422 | 0AFED35D-0B15-4070-A6C4-E762A091EC86 423 | version 424 | 2 425 | 426 | 427 | config 428 | 429 | argument 430 | {query} 431 | passthroughargument 432 | 433 | variables 434 | 435 | link 436 | {query}/blob/master/CONTRIBUTING.md 437 | 438 | 439 | type 440 | alfred.workflow.utility.argument 441 | uid 442 | 60D56C11-AA30-44D1-82E2-67C0A0B87073 443 | version 444 | 1 445 | 446 | 447 | config 448 | 449 | concurrently 450 | 451 | escaping 452 | 102 453 | script 454 | query=$1 455 | 456 | echo -n "${query//}" 457 | scriptargtype 458 | 1 459 | scriptfile 460 | 461 | type 462 | 0 463 | 464 | type 465 | alfred.workflow.action.script 466 | uid 467 | 72B1AA05-3281-415B-9252-9036D705817A 468 | version 469 | 2 470 | 471 | 472 | config 473 | 474 | browser 475 | 476 | spaces 477 | 478 | url 479 | {var:link} 480 | utf8 481 | 482 | 483 | type 484 | alfred.workflow.action.openurl 485 | uid 486 | A2A341B0-792A-43F0-A4F7-7F2755274850 487 | version 488 | 1 489 | 490 | 491 | config 492 | 493 | argument 494 | {query} 495 | passthroughargument 496 | 497 | variables 498 | 499 | link 500 | {query}/edit/master/README.md 501 | 502 | 503 | type 504 | alfred.workflow.utility.argument 505 | uid 506 | AEABCB9D-9232-43D3-8640-84C9451203E0 507 | version 508 | 1 509 | 510 | 511 | readme 512 | Details on how to use this workflow are found in the GitHub repo attached to the workflow. 513 | 514 | Double click this workflow in sidebar -> Open website. 515 | 516 | Post any issues and feature requests you have there. 💜 517 | uidata 518 | 519 | 05C2CDF4-B8F6-48B5-9DCC-75AC001E1500 520 | 521 | xpos 522 | 10 523 | ypos 524 | 10 525 | 526 | 0AFED35D-0B15-4070-A6C4-E762A091EC86 527 | 528 | xpos 529 | 505 530 | ypos 531 | 290 532 | 533 | 238CAD6B-EF29-4AF9-8A6D-A45407BBC0CE 534 | 535 | xpos 536 | 405 537 | ypos 538 | 10 539 | 540 | 2C61650C-01F2-4BC7-AAE0-8C31508A2833 541 | 542 | xpos 543 | 10 544 | ypos 545 | 230 546 | 547 | 3E3F5B1F-5EA1-4271-952C-1B1897B454DE 548 | 549 | xpos 550 | 155 551 | ypos 552 | 40 553 | 554 | 3E8C3225-79D1-43C3-A4E3-583E4B6B152F 555 | 556 | xpos 557 | 165 558 | ypos 559 | 260 560 | 561 | 4F774142-7D29-4E25-8B08-5CCEAA253E53 562 | 563 | note 564 | Search lists 565 | xpos 566 | 255 567 | ypos 568 | 230 569 | 570 | 60D56C11-AA30-44D1-82E2-67C0A0B87073 571 | 572 | xpos 573 | 665 574 | ypos 575 | 320 576 | 577 | 62FC303E-01BA-430E-BC35-C7365486A097 578 | 579 | note 580 | View contributing guidelines 581 | xpos 582 | 755 583 | ypos 584 | 290 585 | 586 | 72B1AA05-3281-415B-9252-9036D705817A 587 | 588 | xpos 589 | 505 590 | ypos 591 | 440 592 | 593 | 790627A4-87DA-408A-BC71-90FA3D9CDF36 594 | 595 | note 596 | Search topics 597 | xpos 598 | 225 599 | ypos 600 | 10 601 | 602 | A2A341B0-792A-43F0-A4F7-7F2755274850 603 | 604 | note 605 | Edit list 606 | xpos 607 | 755 608 | ypos 609 | 440 610 | 611 | AEABCB9D-9232-43D3-8640-84C9451203E0 612 | 613 | xpos 614 | 665 615 | ypos 616 | 470 617 | 618 | C7FE3DF8-D5CD-4468-8CE0-BB050EF48F17 619 | 620 | xpos 621 | 505 622 | ypos 623 | 150 624 | 625 | 626 | version 627 | 2.5.2 628 | webaddress 629 | https://github.com/nikitavoloboev/alfred-learn-anything 630 | 631 | 632 | -------------------------------------------------------------------------------- /workflow/lists.md: -------------------------------------------------------------------------------- 1 | - [Books](https://github.com/learn-anything/books) 2 | - [Courses](https://github.com/learn-anything/courses) 3 | - [Research papers](https://github.com/learn-anything/research-papers) 4 | - [Newsletters](https://github.com/learn-anything/newsletters) 5 | - [Podcasts](https://github.com/learn-anything/podcasts) 6 | - [Blogs](https://github.com/learn-anything/blogs) 7 | - [Talks](https://github.com/learn-anything/talks) 8 | - [Cheat sheets](https://github.com/learn-anything/cheat-sheets) 9 | - [Alfred workflows](https://github.com/learn-anything/alfred-workflows) 10 | - [Chrome extensions](https://github.com/learn-anything/chrome-extensions) 11 | - [Command line tools](https://github.com/learn-anything/command-line-tools) 12 | - [Firefox extensions](https://github.com/learn-anything/firefox-extensions) 13 | - [Programming languages](https://github.com/learn-anything/programming-languages) 14 | - [Safari extensions](https://github.com/learn-anything/safari-extensions) 15 | - [Events](https://github.com/learn-anything/events) 16 | - [Forums](https://github.com/learn-anything/forums) 17 | - [Slack groups](https://github.com/learn-anything/slack-groups) 18 | - [Spectrum communities](https://github.com/learn-anything/spectrum) 19 | - [Telegram groups](https://github.com/learn-anything/telegram-groups) 20 | - [Documentaries](https://github.com/learn-anything/documentaries) 21 | - [Games](https://github.com/learn-anything/games) 22 | - [Movies](https://github.com/learn-anything/movies) 23 | - [TV series](https://github.com/learn-anything/tv-series) 24 | - [YouTube channels](https://github.com/learn-anything/youtube) 25 | - [Humans](https://github.com/learn-anything/humans) 26 | - [iOS apps](https://github.com/learn-anything/ios-apps) 27 | - [macOS apps](https://github.com/learn-anything/macos-apps) 28 | - [Quora](https://github.com/learn-anything/quora) 29 | - [Quotes](https://github.com/learn-anything/quotes) 30 | - [Reddit subreddits](https://github.com/learn-anything/reddit) 31 | - [Stack Exchange sites](https://github.com/learn-anything/stack-exchange) 32 | - [Websites](https://github.com/learn-anything/websites) 33 | - [Awesome Lists](https://github.com/sindresorhus/awesome) 34 | - [Awesome Awesomeness](https://github.com/bayandin/awesome-awesomeness) 35 | --------------------------------------------------------------------------------