├── .env ├── .gitignore ├── .travis.yml ├── 5minphp-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml └── src │ ├── index.php │ └── rollbar.php ├── README.md ├── anek-bot ├── Dockerfile ├── README.md ├── app │ ├── AnekdotChannel.js │ ├── AnekdotData.js │ ├── AnekdotLoader.js │ ├── Bot.js │ ├── RESTServer.js │ ├── RequestData.js │ └── app.js ├── bot-spec.yml ├── docker-compose.yml ├── package.json ├── src │ ├── AnekdotChannel.ts │ ├── AnekdotData.ts │ ├── AnekdotLoader.ts │ ├── Bot.ts │ ├── RESTServer.ts │ ├── RequestData.ts │ └── app.ts ├── tsconfig.json ├── typings.json └── typings │ ├── globals │ ├── body-parser │ │ ├── index.d.ts │ │ └── typings.json │ ├── express-serve-static-core │ │ ├── index.d.ts │ │ └── typings.json │ ├── express │ │ ├── index.d.ts │ │ └── typings.json │ ├── iconv │ │ ├── index.d.ts │ │ └── typings.json │ ├── node │ │ ├── index.d.ts │ │ └── typings.json │ ├── request │ │ ├── index.d.ts │ │ └── typings.json │ ├── serve-static │ │ ├── index.d.ts │ │ └── typings.json │ └── xml2js │ │ ├── index.d.ts │ │ └── typings.json │ └── index.d.ts ├── bot-4-bots ├── .gitignore ├── Bot4Bots.Tests │ ├── Bot4Bots.Tests.xproj │ ├── GithubGatewayTest.cs │ └── project.json ├── Bot4Bots.sln ├── Bot4Bots │ ├── Bot4Bots.xproj │ ├── BotController.cs │ ├── Github │ │ ├── GithubBotSummary.cs │ │ ├── GithubCommitter.cs │ │ ├── GithubGateway.cs │ │ └── GithubService.cs │ ├── Startup.cs │ ├── appsettings.Development.json │ ├── appsettings.json │ └── project.json ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml └── global.json ├── brackets-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── brackets.go ├── brackets_test.go ├── docker-compose.yml └── main.go ├── ci ├── .gitignore ├── README.md ├── bot_configparser.py ├── requirements.in ├── requirements.txt └── run_bot_tests.py ├── converter-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── converter.py ├── db │ ├── __init__.py │ ├── data │ │ ├── __init__.py │ │ └── data.py │ ├── length │ │ ├── __init__.py │ │ └── length.py │ ├── mass │ │ ├── __init__.py │ │ └── mass.py │ ├── temperature │ │ ├── __init__.py │ │ └── temperature.py │ ├── time │ │ ├── __init__.py │ │ └── time.py │ └── volume │ │ ├── __init__.py │ │ └── volume.py ├── docker-compose.yml ├── main.py └── requirements.txt ├── deploy ├── Dockerfile ├── deploy.sh └── main.go ├── docker-bot ├── COPYING ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── bot-spec.yml ├── commands.rb ├── config.ru ├── db.rb ├── docker-bot.rb ├── docker-compose.yml └── podcast.rb ├── docker-compose-deploy.yml ├── docker-compose.yml ├── doit-bot ├── .gitignore ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yaml ├── index.js ├── package.json └── triggers.json ├── etc ├── nginx.conf └── ssl │ └── .keep ├── excerpt-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml ├── main.go └── main_test.go ├── gif-bot ├── Dockerfile ├── README.md ├── _bot-spec.yml ├── config.go ├── docker-compose.yml ├── main.go ├── request.go ├── response.go └── source.go ├── giphy-bot ├── Dockerfile ├── README.md ├── _bot-spec.yml ├── docker-compose.yml ├── main.py └── requirements.txt ├── grabpage-bot ├── .gitignore ├── Dockerfile ├── README.md ├── _bot-spec.yml ├── docker-compose.yml ├── main.py └── requirements.txt ├── guido-bot ├── Dockerfile ├── README.md ├── bot-spec.yml └── docker-compose.yml ├── hcalendar-bot ├── .vscode │ └── launch.json ├── Dockerfile ├── README.md ├── app.js ├── bot-spec.yml ├── docker-compose.yml ├── formatting.js ├── kdate.js └── package.json ├── hello ├── Dockerfile ├── README.md ├── app.psgi ├── bot-spec.yml ├── build ├── cmd ├── cpanfile ├── cpanfile.snapshot ├── docker-compose.yml ├── run └── update_deps ├── karma-bot ├── .gitignore ├── Dockerfile ├── Makefile ├── README.md ├── __init__.py ├── bot-spec.yml ├── docker-compose.yml ├── karma.py ├── requirements.in ├── requirements.txt ├── rt_karma_bot.py ├── run_tests.sh ├── settings.py └── tests │ ├── test_api.py │ └── test_karma.py ├── ksenks-bot ├── Dockerfile ├── README.md ├── audio.py ├── audioread.py ├── bot-spec.yml ├── docker-compose.yml ├── log_handler.py ├── main.py ├── requirements.txt ├── svm_model.pickle └── timeout.py ├── loro-bot ├── .gitignore ├── Dockerfile ├── README.md ├── bot-spec.yml ├── bot.py ├── corpuses │ ├── bobuk │ ├── trump │ └── umputun ├── docker-compose.yml ├── requirements.txt └── wsgi.py ├── lucky ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml └── main.go ├── memberberries ├── .gitignore ├── Controllers │ ├── EventController.cs │ └── InfoController.cs ├── Dockerfile ├── Models │ ├── About.cs │ ├── Answer.cs │ └── Message.cs ├── Program.cs ├── Properties │ └── launchSettings.json ├── README.md ├── Services │ ├── Bot.cs │ └── IBot.cs ├── Startup.cs ├── appsettings.json ├── bot-spec.yml ├── docker-compose.yml └── project.json ├── money-bot ├── Dockerfile ├── README.md ├── app.js ├── bot-spec.yml ├── currency.json ├── docker-compose.yml └── package.json ├── noter-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── gekoreed │ ├── Server.java │ ├── entity │ ├── ChatRequest.java │ └── Response.java │ └── util │ └── Storage.java ├── or-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml ├── main.py └── requirements.txt ├── random-bot ├── Dockerfile ├── README.md ├── answers.json ├── bot-spec.yml ├── docker-compose.yml ├── main.go └── main_test.go ├── rest-voter ├── .gitignore ├── Dockerfile ├── README.md ├── bot-spec.yml ├── build.gradle ├── docker-compose.yml ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ └── main │ ├── kotlin │ └── ru │ │ └── hixon │ │ ├── Application.kt │ │ ├── controllers │ │ └── VoteController.kt │ │ └── domain │ │ ├── InfoResponse.kt │ │ ├── VoteRequest.kt │ │ └── VoteResponse.kt │ └── resources │ └── application.properties ├── rt-repl-bot ├── .dockerignore ├── .gitignore ├── .java.policy ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml ├── project.clj ├── resources │ └── logback.xml ├── src │ └── rt_repl_bot │ │ ├── handler.clj │ │ └── repl.clj └── test │ └── rt_repl_bot │ ├── handler_test.clj │ └── repl_test.clj ├── rtnumber-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml ├── log_handler.py ├── main.py └── requirements.txt ├── run_local.sh ├── sample-go ├── Dockerfile ├── README.md ├── docker-compose.yml └── main.go ├── search-bot ├── Dockerfile ├── Godeps │ ├── Godeps.json │ └── Readme ├── LICENSE ├── README.md ├── bot-spec.yml ├── config │ └── config.go ├── data │ └── .keep ├── docker-compose.yml ├── main.go ├── search │ └── search.go ├── shows │ ├── fetch.go │ ├── fetch_test.go │ ├── model.go │ └── state.go └── vendor │ ├── code.google.com │ └── p │ │ └── cascadia │ │ ├── .hgignore │ │ ├── LICENSE │ │ ├── Makefile │ │ ├── parser.go │ │ └── selector.go │ ├── github.com │ ├── PuerkitoBio │ │ └── goquery │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── array.go │ │ │ ├── doc.go │ │ │ ├── expand.go │ │ │ ├── filter.go │ │ │ ├── iteration.go │ │ │ ├── manipulation.go │ │ │ ├── property.go │ │ │ ├── query.go │ │ │ ├── traversal.go │ │ │ ├── type.go │ │ │ └── utilities.go │ ├── alehano │ │ └── batch │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ └── batch.go │ ├── blevesearch │ │ ├── bleve │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── CONTRIBUTING.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── analysis │ │ │ │ ├── analyzer │ │ │ │ │ └── standard │ │ │ │ │ │ └── standard.go │ │ │ │ ├── datetime │ │ │ │ │ ├── flexible │ │ │ │ │ │ └── flexible.go │ │ │ │ │ └── optional │ │ │ │ │ │ └── optional.go │ │ │ │ ├── freq.go │ │ │ │ ├── lang │ │ │ │ │ └── en │ │ │ │ │ │ ├── analyzer_en.go │ │ │ │ │ │ ├── possessive_filter_en.go │ │ │ │ │ │ ├── stop_filter_en.go │ │ │ │ │ │ └── stop_words_en.go │ │ │ │ ├── test_words.txt │ │ │ │ ├── token │ │ │ │ │ ├── lowercase │ │ │ │ │ │ └── lowercase.go │ │ │ │ │ ├── porter │ │ │ │ │ │ └── porter.go │ │ │ │ │ └── stop │ │ │ │ │ │ └── stop.go │ │ │ │ ├── tokenizer │ │ │ │ │ └── unicode │ │ │ │ │ │ └── unicode.go │ │ │ │ ├── tokenmap.go │ │ │ │ ├── type.go │ │ │ │ └── util.go │ │ │ ├── config.go │ │ │ ├── config_app.go │ │ │ ├── config_disk.go │ │ │ ├── doc.go │ │ │ ├── document │ │ │ │ ├── document.go │ │ │ │ ├── field.go │ │ │ │ ├── field_boolean.go │ │ │ │ ├── field_composite.go │ │ │ │ ├── field_datetime.go │ │ │ │ ├── field_numeric.go │ │ │ │ ├── field_text.go │ │ │ │ └── indexing_options.go │ │ │ ├── error.go │ │ │ ├── index.go │ │ │ ├── index │ │ │ │ ├── analysis.go │ │ │ │ ├── field_cache.go │ │ │ │ ├── index.go │ │ │ │ ├── store │ │ │ │ │ ├── batch.go │ │ │ │ │ ├── boltdb │ │ │ │ │ │ ├── iterator.go │ │ │ │ │ │ ├── reader.go │ │ │ │ │ │ ├── stats.go │ │ │ │ │ │ ├── store.go │ │ │ │ │ │ └── writer.go │ │ │ │ │ ├── gtreap │ │ │ │ │ │ ├── iterator.go │ │ │ │ │ │ ├── reader.go │ │ │ │ │ │ ├── store.go │ │ │ │ │ │ └── writer.go │ │ │ │ │ ├── kvstore.go │ │ │ │ │ ├── merge.go │ │ │ │ │ └── multiget.go │ │ │ │ └── upsidedown │ │ │ │ │ ├── analysis.go │ │ │ │ │ ├── benchmark_all.sh │ │ │ │ │ ├── dump.go │ │ │ │ │ ├── field_dict.go │ │ │ │ │ ├── index_reader.go │ │ │ │ │ ├── reader.go │ │ │ │ │ ├── row.go │ │ │ │ │ ├── row_merge.go │ │ │ │ │ ├── stats.go │ │ │ │ │ ├── upsidedown.go │ │ │ │ │ ├── upsidedown.pb.go │ │ │ │ │ └── upsidedown.proto │ │ │ ├── index_alias.go │ │ │ ├── index_alias_impl.go │ │ │ ├── index_impl.go │ │ │ ├── index_meta.go │ │ │ ├── index_stats.go │ │ │ ├── mapping.go │ │ │ ├── mapping │ │ │ │ ├── analysis.go │ │ │ │ ├── document.go │ │ │ │ ├── field.go │ │ │ │ ├── index.go │ │ │ │ ├── mapping.go │ │ │ │ └── reflect.go │ │ │ ├── numeric │ │ │ │ ├── float.go │ │ │ │ └── prefix_coded.go │ │ │ ├── query.go │ │ │ ├── registry │ │ │ │ ├── analyzer.go │ │ │ │ ├── cache.go │ │ │ │ ├── char_filter.go │ │ │ │ ├── datetime_parser.go │ │ │ │ ├── fragment_formatter.go │ │ │ │ ├── fragmenter.go │ │ │ │ ├── highlighter.go │ │ │ │ ├── index_type.go │ │ │ │ ├── registry.go │ │ │ │ ├── store.go │ │ │ │ ├── token_filter.go │ │ │ │ ├── token_maps.go │ │ │ │ └── tokenizer.go │ │ │ ├── search.go │ │ │ └── search │ │ │ │ ├── collector.go │ │ │ │ ├── collector │ │ │ │ ├── heap.go │ │ │ │ ├── list.go │ │ │ │ ├── slice.go │ │ │ │ └── topn.go │ │ │ │ ├── explanation.go │ │ │ │ ├── facet │ │ │ │ ├── benchmark_data.txt │ │ │ │ ├── facet_builder_datetime.go │ │ │ │ ├── facet_builder_numeric.go │ │ │ │ └── facet_builder_terms.go │ │ │ │ ├── facets_builder.go │ │ │ │ ├── highlight │ │ │ │ ├── format │ │ │ │ │ └── html │ │ │ │ │ │ └── html.go │ │ │ │ ├── fragmenter │ │ │ │ │ └── simple │ │ │ │ │ │ └── simple.go │ │ │ │ ├── highlighter.go │ │ │ │ ├── highlighter │ │ │ │ │ ├── html │ │ │ │ │ │ └── html.go │ │ │ │ │ └── simple │ │ │ │ │ │ ├── fragment_scorer_simple.go │ │ │ │ │ │ └── highlighter_simple.go │ │ │ │ └── term_locations.go │ │ │ │ ├── levenshtein.go │ │ │ │ ├── pool.go │ │ │ │ ├── query │ │ │ │ ├── bool_field.go │ │ │ │ ├── boolean.go │ │ │ │ ├── boost.go │ │ │ │ ├── conjunction.go │ │ │ │ ├── date_range.go │ │ │ │ ├── disjunction.go │ │ │ │ ├── docid.go │ │ │ │ ├── fuzzy.go │ │ │ │ ├── match.go │ │ │ │ ├── match_all.go │ │ │ │ ├── match_none.go │ │ │ │ ├── match_phrase.go │ │ │ │ ├── numeric_range.go │ │ │ │ ├── phrase.go │ │ │ │ ├── prefix.go │ │ │ │ ├── query.go │ │ │ │ ├── query_string.go │ │ │ │ ├── query_string.y │ │ │ │ ├── query_string.y.go │ │ │ │ ├── query_string_lex.go │ │ │ │ ├── query_string_parser.go │ │ │ │ ├── regexp.go │ │ │ │ ├── term.go │ │ │ │ └── wildcard.go │ │ │ │ ├── scorer │ │ │ │ ├── scorer_conjunction.go │ │ │ │ ├── scorer_constant.go │ │ │ │ ├── scorer_disjunction.go │ │ │ │ ├── scorer_term.go │ │ │ │ └── sqrt_cache.go │ │ │ │ ├── search.go │ │ │ │ ├── searcher │ │ │ │ ├── ordered_searchers_list.go │ │ │ │ ├── search_boolean.go │ │ │ │ ├── search_conjunction.go │ │ │ │ ├── search_disjunction.go │ │ │ │ ├── search_docid.go │ │ │ │ ├── search_fuzzy.go │ │ │ │ ├── search_match_all.go │ │ │ │ ├── search_match_none.go │ │ │ │ ├── search_numeric_range.go │ │ │ │ ├── search_phrase.go │ │ │ │ ├── search_regexp.go │ │ │ │ ├── search_term.go │ │ │ │ └── search_term_prefix.go │ │ │ │ ├── sort.go │ │ │ │ └── util.go │ │ ├── go-porterstemmer │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ └── porterstemmer.go │ │ └── segment │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── doc.go │ │ │ ├── maketesttables.go │ │ │ ├── segment.go │ │ │ ├── segment_fuzz.go │ │ │ ├── segment_words.go │ │ │ ├── segment_words.rl │ │ │ └── segment_words_prod.go │ ├── boltdb │ │ └── bolt │ │ │ ├── .gitignore │ │ │ ├── LICENSE │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── appveyor.yml │ │ │ ├── bolt_386.go │ │ │ ├── bolt_amd64.go │ │ │ ├── bolt_arm.go │ │ │ ├── bolt_arm64.go │ │ │ ├── bolt_linux.go │ │ │ ├── bolt_openbsd.go │ │ │ ├── bolt_ppc.go │ │ │ ├── bolt_ppc64.go │ │ │ ├── bolt_ppc64le.go │ │ │ ├── bolt_s390x.go │ │ │ ├── bolt_unix.go │ │ │ ├── bolt_unix_solaris.go │ │ │ ├── bolt_windows.go │ │ │ ├── boltsync_unix.go │ │ │ ├── bucket.go │ │ │ ├── cursor.go │ │ │ ├── db.go │ │ │ ├── doc.go │ │ │ ├── errors.go │ │ │ ├── freelist.go │ │ │ ├── node.go │ │ │ ├── page.go │ │ │ └── tx.go │ ├── golang │ │ └── protobuf │ │ │ ├── LICENSE │ │ │ └── proto │ │ │ ├── Makefile │ │ │ ├── clone.go │ │ │ ├── decode.go │ │ │ ├── encode.go │ │ │ ├── equal.go │ │ │ ├── extensions.go │ │ │ ├── lib.go │ │ │ ├── message_set.go │ │ │ ├── pointer_reflect.go │ │ │ ├── pointer_unsafe.go │ │ │ ├── properties.go │ │ │ ├── text.go │ │ │ └── text_parser.go │ └── steveyen │ │ └── gtreap │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ └── treap.go │ ├── golang.org │ └── x │ │ ├── net │ │ ├── LICENSE │ │ ├── PATENTS │ │ ├── context │ │ │ ├── context.go │ │ │ ├── go17.go │ │ │ └── pre_go17.go │ │ └── html │ │ │ ├── atom │ │ │ ├── atom.go │ │ │ ├── gen.go │ │ │ └── table.go │ │ │ ├── const.go │ │ │ ├── doc.go │ │ │ ├── doctype.go │ │ │ ├── entity.go │ │ │ ├── escape.go │ │ │ ├── foreign.go │ │ │ ├── node.go │ │ │ ├── parse.go │ │ │ ├── render.go │ │ │ └── token.go │ │ └── sys │ │ ├── LICENSE │ │ ├── PATENTS │ │ └── unix │ │ ├── .gitignore │ │ ├── asm.s │ │ ├── asm_darwin_386.s │ │ ├── asm_darwin_amd64.s │ │ ├── asm_darwin_arm.s │ │ ├── asm_darwin_arm64.s │ │ ├── asm_dragonfly_386.s │ │ ├── asm_dragonfly_amd64.s │ │ ├── asm_freebsd_386.s │ │ ├── asm_freebsd_amd64.s │ │ ├── asm_freebsd_arm.s │ │ ├── asm_linux_386.s │ │ ├── asm_linux_amd64.s │ │ ├── asm_linux_arm.s │ │ ├── asm_linux_arm64.s │ │ ├── asm_linux_ppc64x.s │ │ ├── asm_netbsd_386.s │ │ ├── asm_netbsd_amd64.s │ │ ├── asm_netbsd_arm.s │ │ ├── asm_openbsd_386.s │ │ ├── asm_openbsd_amd64.s │ │ ├── asm_solaris_amd64.s │ │ ├── constants.go │ │ ├── env_unix.go │ │ ├── env_unset.go │ │ ├── flock.go │ │ ├── flock_linux_32bit.go │ │ ├── gccgo.go │ │ ├── gccgo_c.c │ │ ├── gccgo_linux_amd64.go │ │ ├── mkall.sh │ │ ├── mkerrors.sh │ │ ├── mksyscall.pl │ │ ├── mksyscall_solaris.pl │ │ ├── mksysctl_openbsd.pl │ │ ├── mksysnum_darwin.pl │ │ ├── mksysnum_dragonfly.pl │ │ ├── mksysnum_freebsd.pl │ │ ├── mksysnum_linux.pl │ │ ├── mksysnum_netbsd.pl │ │ ├── mksysnum_openbsd.pl │ │ ├── race.go │ │ ├── race0.go │ │ ├── sockcmsg_linux.go │ │ ├── sockcmsg_unix.go │ │ ├── str.go │ │ ├── syscall.go │ │ ├── syscall_bsd.go │ │ ├── syscall_darwin.go │ │ ├── syscall_darwin_386.go │ │ ├── syscall_darwin_amd64.go │ │ ├── syscall_darwin_arm.go │ │ ├── syscall_darwin_arm64.go │ │ ├── syscall_dragonfly.go │ │ ├── syscall_dragonfly_386.go │ │ ├── syscall_dragonfly_amd64.go │ │ ├── syscall_freebsd.go │ │ ├── syscall_freebsd_386.go │ │ ├── syscall_freebsd_amd64.go │ │ ├── syscall_freebsd_arm.go │ │ ├── syscall_linux.go │ │ ├── syscall_linux_386.go │ │ ├── syscall_linux_amd64.go │ │ ├── syscall_linux_arm.go │ │ ├── syscall_linux_arm64.go │ │ ├── syscall_linux_ppc64x.go │ │ ├── syscall_netbsd.go │ │ ├── syscall_netbsd_386.go │ │ ├── syscall_netbsd_amd64.go │ │ ├── syscall_netbsd_arm.go │ │ ├── syscall_no_getwd.go │ │ ├── syscall_openbsd.go │ │ ├── syscall_openbsd_386.go │ │ ├── syscall_openbsd_amd64.go │ │ ├── syscall_solaris.go │ │ ├── syscall_solaris_amd64.go │ │ ├── syscall_unix.go │ │ ├── types_darwin.go │ │ ├── types_dragonfly.go │ │ ├── types_freebsd.go │ │ ├── types_linux.go │ │ ├── types_netbsd.go │ │ ├── types_openbsd.go │ │ ├── types_solaris.go │ │ ├── zerrors_darwin_386.go │ │ ├── zerrors_darwin_amd64.go │ │ ├── zerrors_darwin_arm.go │ │ ├── zerrors_darwin_arm64.go │ │ ├── zerrors_dragonfly_386.go │ │ ├── zerrors_dragonfly_amd64.go │ │ ├── zerrors_freebsd_386.go │ │ ├── zerrors_freebsd_amd64.go │ │ ├── zerrors_freebsd_arm.go │ │ ├── zerrors_linux_386.go │ │ ├── zerrors_linux_amd64.go │ │ ├── zerrors_linux_arm.go │ │ ├── zerrors_linux_arm64.go │ │ ├── zerrors_linux_ppc64.go │ │ ├── zerrors_linux_ppc64le.go │ │ ├── zerrors_netbsd_386.go │ │ ├── zerrors_netbsd_amd64.go │ │ ├── zerrors_netbsd_arm.go │ │ ├── zerrors_openbsd_386.go │ │ ├── zerrors_openbsd_amd64.go │ │ ├── zerrors_solaris_amd64.go │ │ ├── zsyscall_darwin_386.go │ │ ├── zsyscall_darwin_amd64.go │ │ ├── zsyscall_darwin_arm.go │ │ ├── zsyscall_darwin_arm64.go │ │ ├── zsyscall_dragonfly_386.go │ │ ├── zsyscall_dragonfly_amd64.go │ │ ├── zsyscall_freebsd_386.go │ │ ├── zsyscall_freebsd_amd64.go │ │ ├── zsyscall_freebsd_arm.go │ │ ├── zsyscall_linux_386.go │ │ ├── zsyscall_linux_amd64.go │ │ ├── zsyscall_linux_arm.go │ │ ├── zsyscall_linux_arm64.go │ │ ├── zsyscall_linux_ppc64.go │ │ ├── zsyscall_linux_ppc64le.go │ │ ├── zsyscall_netbsd_386.go │ │ ├── zsyscall_netbsd_amd64.go │ │ ├── zsyscall_netbsd_arm.go │ │ ├── zsyscall_openbsd_386.go │ │ ├── zsyscall_openbsd_amd64.go │ │ ├── zsyscall_solaris_amd64.go │ │ ├── zsysctl_openbsd.go │ │ ├── zsysnum_darwin_386.go │ │ ├── zsysnum_darwin_amd64.go │ │ ├── zsysnum_darwin_arm.go │ │ ├── zsysnum_darwin_arm64.go │ │ ├── zsysnum_dragonfly_386.go │ │ ├── zsysnum_dragonfly_amd64.go │ │ ├── zsysnum_freebsd_386.go │ │ ├── zsysnum_freebsd_amd64.go │ │ ├── zsysnum_freebsd_arm.go │ │ ├── zsysnum_linux_386.go │ │ ├── zsysnum_linux_amd64.go │ │ ├── zsysnum_linux_arm.go │ │ ├── zsysnum_linux_arm64.go │ │ ├── zsysnum_linux_ppc64.go │ │ ├── zsysnum_linux_ppc64le.go │ │ ├── zsysnum_netbsd_386.go │ │ ├── zsysnum_netbsd_amd64.go │ │ ├── zsysnum_netbsd_arm.go │ │ ├── zsysnum_openbsd_386.go │ │ ├── zsysnum_openbsd_amd64.go │ │ ├── zsysnum_solaris_amd64.go │ │ ├── ztypes_darwin_386.go │ │ ├── ztypes_darwin_amd64.go │ │ ├── ztypes_darwin_arm.go │ │ ├── ztypes_darwin_arm64.go │ │ ├── ztypes_dragonfly_386.go │ │ ├── ztypes_dragonfly_amd64.go │ │ ├── ztypes_freebsd_386.go │ │ ├── ztypes_freebsd_amd64.go │ │ ├── ztypes_freebsd_arm.go │ │ ├── ztypes_linux_386.go │ │ ├── ztypes_linux_amd64.go │ │ ├── ztypes_linux_arm.go │ │ ├── ztypes_linux_arm64.go │ │ ├── ztypes_linux_ppc64.go │ │ ├── ztypes_linux_ppc64le.go │ │ ├── ztypes_netbsd_386.go │ │ ├── ztypes_netbsd_amd64.go │ │ ├── ztypes_netbsd_arm.go │ │ ├── ztypes_openbsd_386.go │ │ ├── ztypes_openbsd_amd64.go │ │ └── ztypes_solaris_amd64.go │ └── gopkg.in │ └── robfig │ └── cron.v2 │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── constantdelay.go │ ├── cron.go │ ├── doc.go │ ├── parser.go │ └── spec.go ├── sovet-bot ├── Dockerfile ├── README.md ├── _bot-spec.yml ├── app.js ├── docker-compose.yml └── package.json ├── stat-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml ├── lib │ └── StatBot.pm └── stat-bot.pl ├── timezone-bot ├── Dockerfile ├── README.rst ├── _bot-spec.yml ├── config │ └── common.cfg ├── docker-compose.yml ├── requirements │ ├── common.in │ ├── local.in │ ├── local.txt │ ├── production.in │ └── production.txt ├── tasks.py ├── tests.py └── timezone_bot.py ├── tweet-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml ├── main.py └── requirements.txt ├── weather-bot ├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md ├── bot-spec.yml ├── build.gradle ├── docker-compose.yml ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ ├── main │ ├── kotlin │ │ └── rt │ │ │ └── bot │ │ │ └── weatherbot │ │ │ ├── BotResponse.kt │ │ │ ├── Event.kt │ │ │ ├── Main.kt │ │ │ ├── openweather │ │ │ ├── Clouds.kt │ │ │ ├── Geolocation.kt │ │ │ ├── IWeatherService.kt │ │ │ ├── Metrics.kt │ │ │ ├── Sys.kt │ │ │ ├── Weather.kt │ │ │ ├── WeatherData.kt │ │ │ ├── WeatherServiceImpl.kt │ │ │ └── Wind.kt │ │ │ └── utils │ │ │ └── StringUtils.kt │ └── resources │ │ └── logback.xml │ └── test │ ├── kotlin │ └── rt │ │ └── bot │ │ └── weatherbot │ │ └── utils │ │ └── StringUtilsT.kt │ └── resources │ └── logback-test.xml └── wiki-bot ├── Dockerfile ├── README.md ├── bot-spec.yml ├── docker-compose.yml ├── mvnw ├── mvnw.cmd ├── pom.xml ├── rtbot.iml ├── src ├── main │ └── java │ │ └── com │ │ └── m11 │ │ ├── Bot.java │ │ ├── RtbotApplication.java │ │ ├── RtbotController.java │ │ └── WikiHandler.java └── test │ └── java │ └── com │ └── m11 │ ├── RtbotApplicationTests.java │ └── WikiHandlerTest.java └── target ├── classes └── com │ └── m11 │ ├── Bot.class │ ├── RtbotApplication.class │ ├── RtbotController.class │ └── WikiHandler.class ├── maven-archiver └── pom.properties ├── maven-status └── maven-compiler-plugin │ ├── compile │ └── default-compile │ │ ├── createdFiles.lst │ │ └── inputFiles.lst │ └── testCompile │ └── default-testCompile │ ├── createdFiles.lst │ └── inputFiles.lst ├── rtbot-0.0.1-SNAPSHOT.jar ├── rtbot-0.0.1-SNAPSHOT.jar.original ├── surefire-reports ├── TEST-com.m11.RtbotApplicationTests.xml ├── TEST-com.m11.WikiHandlerTest.xml ├── com.m11.RtbotApplicationTests.txt └── com.m11.WikiHandlerTest.txt └── test-classes └── com └── m11 ├── RtbotApplicationTests.class └── WikiHandlerTest.class /.env: -------------------------------------------------------------------------------- 1 | LETSENCRYPT=true 2 | SSL_KEY=le-key.pem 3 | SSL_CERT=le-crt.pem 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea 3 | *.pyc 4 | __pycache__ 5 | etc/ssl/* 6 | .vscode 7 | docker-bot/radio-t-docker-bot.db 8 | -------------------------------------------------------------------------------- /5minphp-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:7.0-alpine 2 | 3 | COPY ./src /bot 4 | WORKDIR /bot/ 5 | 6 | EXPOSE 8080 7 | 8 | CMD ["php", "-S", "0.0.0.0:8080"] 9 | -------------------------------------------------------------------------------- /5minphp-bot/README.md: -------------------------------------------------------------------------------- 1 | #Пятиминутка PHP - бот для Радио-Т 2 | 3 | Если в чате упоминается PHP, то бот сообщает какой-то интересный и полезный факт об этом языке! 4 | База знаний постоянно пополняется! 5 | 6 | Оригинальный репозиторий бота: https://github.com/pqr/5minphp-bot -------------------------------------------------------------------------------- /5minphp-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "5minphp-bot" 2 | bot_display_name: "Пятиминутка PHP" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | - "Как дела?" 7 | - "Один два три" 8 | 9 | test_cases: 10 | - command: "пятиминутка, обновись" 11 | result: "^У меня для вас есть свежие факты про PHP." 12 | 13 | - command: "расскажи о php" 14 | result: ".+" 15 | -------------------------------------------------------------------------------- /5minphp-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | 5minphp-bot: 2 | build: . 3 | container_name: 5minphp-bot 4 | hostname: 5minphp-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /anek-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:7-alpine 2 | 3 | ENV NODE_PATH=.:/usr/lib/node_modules:/node_modules 4 | 5 | RUN set -x && \ 6 | npm install --silent -g nodemon mocha && \ 7 | mkdir -p /node_modules 8 | 9 | COPY ./package.json /package.json 10 | RUN npm install --silent --prefix / 11 | 12 | COPY ./app /app 13 | WORKDIR /app 14 | 15 | EXPOSE 8080 16 | CMD ["node", "/app/app.js"] 17 | -------------------------------------------------------------------------------- /anek-bot/README.md: -------------------------------------------------------------------------------- 1 | **Описание** 2 | 3 | Бот для [ чата Радио-Т](https://chat.radio-t.com/) 4 | 5 | Подгружает список анекдотов по разным темам из RSS сайта anekdot.ru 6 | 7 | Реагирует на фразы в которой есть слова 'расскажи' и 'анекдот', отвечая анекдотом из основного списка (про программистов ) 8 | 9 | Также знает несколько дополнительных тем: 10 | + интернет 11 | + твиттер 12 | + Гейтс 13 | + iphone 14 | 15 | На запрос 'расскажи анекдот про твиттер', ответит анекдотом про твиттер 16 | 17 | **Структура проекта** 18 | 19 | Папка `app` - В эту папку траншпилируется исходники из TypeScript (TS) в JavaScript 20 | 21 | Папка `src` - Исходники на TS 22 | 23 | Папка `typings` - Определения необходимые TS для работы с JS библиотеками 24 | 25 | `tsconfig.json` - настройки компилятора TS 26 | 27 | `typings.json` - настройки утилиты [typings](https://github.com/typings/typings) 28 | 29 | 30 | Для тестирования `curl`-ом нужно указать `content-type` 31 | ``` 32 | curl \ 33 | -v \ 34 | -X POST \ 35 | -d '{"text":"Расскажи анекдот","username":123,"display_name":"login"}' \ 36 | -H 'content-type:application/json' http://192.168.0.30:8080/event 37 | ``` -------------------------------------------------------------------------------- /anek-bot/app/AnekdotData.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var AnekdotData = (function () { 3 | function AnekdotData() { 4 | } 5 | AnekdotData.parseFromObject = function (o) { 6 | var anekdot = new AnekdotData(); 7 | anekdot.guid = o.guid[0]; 8 | anekdot.title = o.title[0]; 9 | anekdot.pubDate = o.pubDate[0]; 10 | anekdot.description = o.description[0]; 11 | anekdot.description = anekdot.description.replace(/
/g, " \\n"); 12 | anekdot.description = anekdot.description.replace(/- /g, "— "); 13 | return anekdot; 14 | }; 15 | AnekdotData.getDefaultAnekdot = function () { 16 | var anekdot = new AnekdotData(); 17 | anekdot.description = "Забыл все анекдоты"; 18 | return anekdot; 19 | }; 20 | return AnekdotData; 21 | }()); 22 | exports.AnekdotData = AnekdotData; 23 | -------------------------------------------------------------------------------- /anek-bot/app/RequestData.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var RequestData = (function () { 3 | function RequestData() { 4 | } 5 | RequestData.parseFromObject = function (data) { 6 | for (var _i = 0, _a = RequestData.fields; _i < _a.length; _i++) { 7 | var field = _a[_i]; 8 | if (!data[field]) { 9 | throw "Error. required field " + field + " not set"; 10 | } 11 | } 12 | var requestData = new RequestData(); 13 | for (var _b = 0, _c = RequestData.fields; _b < _c.length; _b++) { 14 | var field = _c[_b]; 15 | requestData[field] = data[field]; 16 | } 17 | return requestData; 18 | }; 19 | RequestData.fields = ['text', 'username', 'display_name']; 20 | return RequestData; 21 | }()); 22 | exports.RequestData = RequestData; 23 | -------------------------------------------------------------------------------- /anek-bot/app/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /// 3 | var RESTServer_1 = require("./RESTServer"); 4 | var AnekdotLoader_1 = require("./AnekdotLoader"); 5 | var AnekdotChannel_1 = require("./AnekdotChannel"); 6 | var Bot_1 = require("./Bot"); 7 | console.log("Anek-bot starting"); 8 | var loader = new AnekdotLoader_1.AnekdotLoader(); 9 | var channels = []; 10 | channels.push(new AnekdotChannel_1.AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/26.xml", [])); 11 | channels.push(new AnekdotChannel_1.AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/21.xml", ["твиттер", "twitter"])); 12 | channels.push(new AnekdotChannel_1.AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/33.xml", ["гейтс"])); 13 | channels.push(new AnekdotChannel_1.AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/37.xml", ["интернет"])); 14 | channels.push(new AnekdotChannel_1.AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/40.xml", ["apple", "эппл", "iphone", "айфон", "ipad"])); 15 | var bot = new Bot_1.Bot(channels); 16 | var server = new RESTServer_1.RESTServer(bot); 17 | -------------------------------------------------------------------------------- /anek-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "anek-bot" 2 | 3 | ignored_commands: 4 | - "Привет" 5 | - "анекдот" 6 | - "Один два три" 7 | 8 | test_cases: 9 | - command: "расскажи анекдот" 10 | result: ".+" 11 | 12 | - command: "Расскажи анекдот про программиста" 13 | result: ".+" 14 | 15 | - command: "Расскажи смешной анекдот про программиста" 16 | result: ".+" 17 | -------------------------------------------------------------------------------- /anek-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | node: 2 | build: . 3 | ports: 4 | - "8080:8080" 5 | log_driver: "json-file" 6 | log_opt: 7 | max-size: "5m" 8 | max-file: "10" 9 | restart: always -------------------------------------------------------------------------------- /anek-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anek-bot", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | "body-parser": "~1.13.2", 7 | "cookie-parser": "~1.3.5", 8 | "express": "~4.14.0", 9 | "request": "^2.72.0", 10 | "xml2js": "*" 11 | }, 12 | "devDependencies": { 13 | "chai": "^3.5.0" 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /anek-bot/src/AnekdotData.ts: -------------------------------------------------------------------------------- 1 | export class AnekdotData { 2 | guid: string; 3 | title: string; 4 | pubDate: string; 5 | description: string; 6 | 7 | public static parseFromObject(o: any) { 8 | var anekdot = new AnekdotData(); 9 | anekdot.guid = o.guid[0]; 10 | anekdot.title = o.title[0]; 11 | anekdot.pubDate = o.pubDate[0]; 12 | anekdot.description = o.description[0]; 13 | anekdot.description = anekdot.description.replace(/
/g, " \\n"); 14 | anekdot.description = anekdot.description.replace(/- /g, "— "); 15 | 16 | return anekdot; 17 | } 18 | 19 | public static getDefaultAnekdot(): AnekdotData { 20 | var anekdot = new AnekdotData(); 21 | anekdot.description = "Забыл все анекдоты"; 22 | return anekdot; 23 | } 24 | } -------------------------------------------------------------------------------- /anek-bot/src/RequestData.ts: -------------------------------------------------------------------------------- 1 | export class RequestData { 2 | public text: string; 3 | public username: string; 4 | public display_name: string; 5 | 6 | private static fields = ['text', 'username', 'display_name']; 7 | 8 | public static parseFromObject(data: any): RequestData { 9 | for (var field of RequestData.fields) { 10 | if (!data[field]) { 11 | throw `Error. required field ${field} not set`; 12 | } 13 | } 14 | 15 | var requestData = new RequestData(); 16 | for (var field of RequestData.fields) { 17 | requestData[field] = data[field]; 18 | } 19 | 20 | return requestData; 21 | } 22 | } -------------------------------------------------------------------------------- /anek-bot/src/app.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import {RESTServer} from "./RESTServer"; 3 | import {AnekdotLoader} from "./AnekdotLoader"; 4 | import {AnekdotChannel} from "./AnekdotChannel"; 5 | import {Bot} from "./Bot"; 6 | 7 | console.log("Anek-bot starting"); 8 | 9 | var loader = new AnekdotLoader(); 10 | var channels: AnekdotChannel[] = []; 11 | channels.push(new AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/26.xml", [])); 12 | channels.push(new AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/21.xml", ["твиттер", "twitter"])); 13 | channels.push(new AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/33.xml", ["гейтс"])); 14 | channels.push(new AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/37.xml", ["интернет"])); 15 | channels.push(new AnekdotChannel(loader, "https://www.anekdot.ru/rss/tag/40.xml", ["apple", "эппл", "iphone", "айфон", "ipad"])); 16 | 17 | var bot = new Bot(channels); 18 | 19 | var server = new RESTServer(bot); -------------------------------------------------------------------------------- /anek-bot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "noImplicitAny": false, 6 | "sourceMap": false, 7 | "outDir": "app", 8 | "watch": true 9 | }, 10 | "exclude": [ 11 | "node_modules" 12 | ] 13 | } -------------------------------------------------------------------------------- /anek-bot/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "anek-bot", 3 | "dependencies": {} 4 | } 5 | -------------------------------------------------------------------------------- /anek-bot/typings/globals/body-parser/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/6227a28e56f9c085733635ed1c9189f17e425431/body-parser/body-parser.d.ts", 5 | "raw": "registry:dt/body-parser#0.0.0+20160619023215", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/6227a28e56f9c085733635ed1c9189f17e425431/body-parser/body-parser.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /anek-bot/typings/globals/express-serve-static-core/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/efa9f6a496671c274e402ce0361d4b0cab5d632f/express-serve-static-core/express-serve-static-core.d.ts", 5 | "raw": "registry:dt/express-serve-static-core#4.0.0+20161012061536", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/efa9f6a496671c274e402ce0361d4b0cab5d632f/express-serve-static-core/express-serve-static-core.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /anek-bot/typings/globals/express/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/5fd6d6b4eaabda87d19ad13b7d6709443617ddd8/express/express.d.ts", 5 | "raw": "registry:dt/express#4.0.0+20160708185218", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/5fd6d6b4eaabda87d19ad13b7d6709443617ddd8/express/express.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /anek-bot/typings/globals/iconv/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7ecabec1bf754c8fac3b1de8b5bb91f7d6d45380/iconv/iconv.d.ts", 5 | "raw": "registry:dt/iconv#2.1.11+20160417151847", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7ecabec1bf754c8fac3b1de8b5bb91f7d6d45380/iconv/iconv.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /anek-bot/typings/globals/node/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/125165e3c22f28c4cb00525ca1a7b3f83c112e9f/node/node.d.ts", 5 | "raw": "registry:dt/node#6.0.0+20161110151007", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/125165e3c22f28c4cb00525ca1a7b3f83c112e9f/node/node.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /anek-bot/typings/globals/request/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/658d360c6a8611e76f7cc75c07fcd0f02055ffc4/request/request.d.ts", 5 | "raw": "registry:dt/request#0.0.0+20160726020908", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/658d360c6a8611e76f7cc75c07fcd0f02055ffc4/request/request.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /anek-bot/typings/globals/serve-static/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/26a1f8c44f5fe76168df717020bfb93839b63db3/serve-static/serve-static.d.ts", 5 | "raw": "registry:dt/serve-static#0.0.0+20160606155157", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/26a1f8c44f5fe76168df717020bfb93839b63db3/serve-static/serve-static.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /anek-bot/typings/globals/xml2js/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/xml2js/xml2js.d.ts", 5 | "raw": "registry:dt/xml2js#0.0.0+20160317120654", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/xml2js/xml2js.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /anek-bot/typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | /// 8 | /// 9 | -------------------------------------------------------------------------------- /bot-4-bots/Bot4Bots.Tests/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | 4 | "testRunner": "nunit", 5 | 6 | "dependencies": { 7 | "Microsoft.NETCore.App": { 8 | "type": "platform", 9 | "version": "1.1.0" 10 | }, 11 | "NUnit": "3.5.0", 12 | "dotnet-test-nunit": "3.4.0-beta-3", 13 | "Bot4Bots": "1.0.0", 14 | "Microsoft.DotNet.InternalAbstractions": "1.0.0" 15 | }, 16 | 17 | "frameworks": { 18 | "netcoreapp1.1": { 19 | "imports": [ 20 | "dnxcore50", 21 | "portable-net45+win8" 22 | ] 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /bot-4-bots/Bot4Bots/Bot4Bots.xproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 25a7f6fa-eefe-4b13-a9fc-7074a8d5aaf8 10 | MetaBot 11 | .\obj 12 | .\bin\ 13 | v4.5.2 14 | 15 | 16 | 2.0 17 | 18 | 19 | -------------------------------------------------------------------------------- /bot-4-bots/Bot4Bots/Github/GithubBotSummary.cs: -------------------------------------------------------------------------------- 1 | namespace Bot4Bots.Github 2 | { 3 | public class GithubBotSummary 4 | { 5 | public string Name { get; set; } 6 | public string Link { get; set; } 7 | public GithubCommitter CreatedBy { get; set; } 8 | public GithubCommitter LastChangedBy { get; set; } 9 | 10 | } 11 | } -------------------------------------------------------------------------------- /bot-4-bots/Bot4Bots/Github/GithubCommitter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Bot4Bots.Github 4 | { 5 | public class GithubCommitter 6 | { 7 | public string User { get; set; } 8 | public DateTime CommitDate { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /bot-4-bots/Bot4Bots/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /bot-4-bots/Bot4Bots/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Information", 6 | "System": "Error", 7 | "Microsoft": "Error" 8 | } 9 | }, 10 | "APP_TARGET_USER": "umputun", 11 | "APP_TARGET_REPO": "rt-bot", 12 | "APP_DATA_REFRESH_SECONDS": "1800" 13 | } -------------------------------------------------------------------------------- /bot-4-bots/Bot4Bots/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "buildOptions": { 4 | "emitEntryPoint": true 5 | }, 6 | 7 | "dependencies": { 8 | "Microsoft.NETCore.App": { 9 | "type": "platform", 10 | "version": "1.1.0" 11 | }, 12 | "HtmlAgilityPack.NetCore": "1.5.0.1", 13 | "HtmlAgilityPack.CssSelectors.NetCore": "1.0.0", 14 | "Microsoft.AspNetCore.Mvc": "1.1.0", 15 | "Microsoft.AspNetCore.Routing": "1.1.0", 16 | "Microsoft.AspNetCore.Owin": "1.1.0", 17 | "Microsoft.AspNetCore.Server.Kestrel": "1.1.0", 18 | "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0", 19 | "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0", 20 | "Microsoft.Extensions.Configuration.Json": "1.1.0", 21 | "Microsoft.Extensions.Configuration.CommandLine": "1.1.0", 22 | "Microsoft.Extensions.Logging": "1.1.0", 23 | "Microsoft.Extensions.Logging.Console": "1.1.0", 24 | "Microsoft.Extensions.Logging.Debug": "1.1.0", 25 | "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0" 26 | }, 27 | 28 | "frameworks": { 29 | "netcoreapp1.1": { 30 | "imports": "dnxcore50" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /bot-4-bots/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:1.1-sdk-projectjson 2 | 3 | ENV ASPNETCORE_ENVIRONMENT Production 4 | 5 | RUN mkdir /app 6 | WORKDIR /app 7 | COPY ./Bot4Bots/project.json /app 8 | RUN dotnet restore 9 | COPY ./Bot4Bots /app 10 | RUN dotnet build 11 | 12 | EXPOSE 8080/tcp 13 | 14 | CMD ["dotnet", "run"] 15 | -------------------------------------------------------------------------------- /bot-4-bots/README.md: -------------------------------------------------------------------------------- 1 | # bot-4-bots 2 | Выводит расширенную информацию о существующих ботах для чата radio-t. 3 | 4 | ## Команды 5 | `/bots summary` | `/сводка ботов` - выводит информацию о ботах из Github: кем и когда бот был создан и изменен в последний раз. 6 | ``` 7 | http POST https://bot.radio-t.com/api/bot-4-bots/event text='/bots summary' 8 | ``` 9 | -------------------------------------------------------------------------------- /bot-4-bots/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "bot-4-bots" 2 | bot_display_name: "bot-4-bots" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | - "Как дела?" 7 | 8 | test_cases: 9 | - command: "/bots summary" 10 | result: ".+" 11 | 12 | - command: "/сводка ботов" 13 | result: ".+" 14 | -------------------------------------------------------------------------------- /bot-4-bots/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | bot-4-bots: 5 | build: . 6 | container_name: bot-4-bots_standalone 7 | ports: 8 | - "8080:8080" 9 | -------------------------------------------------------------------------------- /bot-4-bots/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "projects":[ 3 | "Bot4Bots", 4 | "Bot4Bots.Tests" 5 | ] 6 | } -------------------------------------------------------------------------------- /brackets-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | ADD . /go/src/github.com/umputun/rt-bot/brackets-bot 4 | RUN \ 5 | cd /go/src/github.com/umputun/rt-bot/brackets-bot && \ 6 | go get -v && \ 7 | go build -o /srv/brackets-bot && \ 8 | rm -rf /go/src/* 9 | 10 | EXPOSE 8080 11 | WORKDIR /srv 12 | CMD ["/srv/brackets-bot"] 13 | -------------------------------------------------------------------------------- /brackets-bot/README.md: -------------------------------------------------------------------------------- 1 | # Brackets bot 2 | 3 | ## Зачем этот бот нужен? 4 | 5 | Как говорит нам [классический xkcd](https://xkcd.com/859/) ([ru](http://xkcd.ru/859/)): 6 | 7 | ![xkcd859ru](http://xkcd.ru/i/859_v3.png) 8 | 9 | **Brackets bot** призван устранить это напряжение. 10 | 11 | ## Что он делает? 12 | 13 | 1. Скобок нет (`foo`) или все скобки верно закрыты (`(foo)`) 14 | 15 | Ничего. 16 | 17 | 2. Скобки слишком закрыты (`foo)))`) 18 | 19 | Ничего. 20 | 21 | 3. Скобки неконсистентны (`[(foo])`) 22 | 23 | Ничего. 24 | 25 | 4. Скобки консистентны, но не все скобки закрыты (`foo(((`) 26 | 27 | Закрывает незакрытые скобки (`)))`) и напоминает автору сообщения о том, что надо закрывать скобки. -------------------------------------------------------------------------------- /brackets-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | defaults: 2 | username: "test" 3 | display_name: "Test" 4 | 5 | bot_name: "brackets-bot" 6 | 7 | ignored_commands: 8 | - "(( Привет ))" 9 | - "{[Привет]}" 10 | - "(((Привет)))" 11 | 12 | test_cases: 13 | - command: "(((Привет))" 14 | result: "\\)\\nЗакрывай скобки, @test" 15 | 16 | - command: "[((Привет))" 17 | result: "]\\nЗакрывай скобки, @test" 18 | 19 | - command: 20 | text: "{{((Привет)" 21 | username: "alex" 22 | result: "\\)}}\\nЗакрывай скобки, @alex" 23 | -------------------------------------------------------------------------------- /brackets-bot/brackets_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func TestBracketsGood(t *testing.T) { 6 | cases := []struct { 7 | in, want string 8 | }{ 9 | {"(", ")"}, 10 | {"", ""}, 11 | {"((()", "))"}, 12 | {"(([", "]))"}, 13 | {"()()()([{", "}])"}, 14 | {":(", ""}, 15 | {":-(", ""}, 16 | {"(:(()", ")"}, 17 | } 18 | for _, c := range cases { 19 | result, err := processString(c.in) 20 | if err != nil { 21 | t.Errorf("Input: '%s'. Error: '%s", c.in, err.Error()) 22 | } 23 | if result != c.want { 24 | t.Errorf("Input: '%s'. Wanted: '%s'. Got: '%s'", c.in, c.want, result) 25 | } 26 | } 27 | } 28 | 29 | func TestBracketsBad(t *testing.T) { 30 | cases := []struct { 31 | in string 32 | err error 33 | }{ 34 | {"(]", inconsistentError}, 35 | {"(({]", inconsistentError}, 36 | } 37 | for _, c := range cases { 38 | _, err := processString(c.in) 39 | if err != c.err { 40 | t.Errorf("Input: '%s'. Wanted: '%s'. Got: '%s'", c.in, err.Error(), c.err.Error()) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /brackets-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | brackets-bot: 2 | build: . 3 | container_name: brackets-bot 4 | hostname: brackets-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /ci/.gitignore: -------------------------------------------------------------------------------- 1 | env/ 2 | -------------------------------------------------------------------------------- /ci/requirements.in: -------------------------------------------------------------------------------- 1 | pyyaml 2 | requests 3 | -------------------------------------------------------------------------------- /ci/requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile --output-file requirements.txt requirements.in 6 | # 7 | pyyaml==3.12 8 | requests==2.11.1 9 | -------------------------------------------------------------------------------- /converter-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | 3 | COPY requirements.txt /tmp/ 4 | RUN pip install -r /tmp/requirements.txt 5 | 6 | RUN mkdir /usr/converter-bot 7 | COPY . /usr/converter-bot/ 8 | WORKDIR /usr/converter-bot/ 9 | 10 | EXPOSE 8080 11 | 12 | CMD ["python", "main.py"] 13 | -------------------------------------------------------------------------------- /converter-bot/README.md: -------------------------------------------------------------------------------- 1 | # Бот для чата [Радио-Т](https://github.com/umputun/rt-bot) 2 | 3 | ## Описание 4 | Бот конвертер. Если сообщение начинается с цифры и в тексте есть упоминания единиц измерения, бот конвертирует значение. 5 | 6 | 7 | ### Пример 1 8 | Сообщение: 9 | ```json 10 | { 11 | text: "1 миля это сколько?", 12 | username: "test", 13 | display_name: "test" 14 | } 15 | ``` 16 | 17 | Ответ: 18 | **_test_** упомянул 1 миля 19 | 20 | Метр 1609.344 21 | 22 | Километр 1.609 23 | 24 | Миллиметр 1609344.0 25 | 26 | Дециметр 16093.44 27 | 28 | Дюйм 63359.873 29 | 30 | Сантиметр 160934.4 31 | 32 | Фут 5280.0 33 | 34 | ### Пример 2 35 | Сообщение: 36 | ```json 37 | { 38 | text: "1 литр это сколько пинт", 39 | username: "test", 40 | display_name: "test" 41 | } 42 | ``` 43 | 44 | Ответ: 45 | **_test_** упомянул 1 литр 46 | 47 | Пинта 2.113 48 | 49 | ### Пример ответа в json 50 | Сообщение: 51 | ```json 52 | { 53 | "text": "**_test_** упомянул 1 литр \\nПинта 2.113 ", 54 | "bot": "converter-bot" 55 | } 56 | ``` -------------------------------------------------------------------------------- /converter-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "converter-bot" 2 | bot_display_name: "converter-bot" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | - "Как дела?" 7 | 8 | test_cases: 9 | - command: "1 метр в сантиметрах" 10 | result: ".+" 11 | 12 | - command: "10 мегабайт" 13 | result: ".+" 14 | -------------------------------------------------------------------------------- /converter-bot/db/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/converter-bot/db/__init__.py -------------------------------------------------------------------------------- /converter-bot/db/data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/converter-bot/db/data/__init__.py -------------------------------------------------------------------------------- /converter-bot/db/length/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/converter-bot/db/length/__init__.py -------------------------------------------------------------------------------- /converter-bot/db/mass/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/converter-bot/db/mass/__init__.py -------------------------------------------------------------------------------- /converter-bot/db/temperature/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/converter-bot/db/temperature/__init__.py -------------------------------------------------------------------------------- /converter-bot/db/time/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/converter-bot/db/time/__init__.py -------------------------------------------------------------------------------- /converter-bot/db/volume/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/converter-bot/db/volume/__init__.py -------------------------------------------------------------------------------- /converter-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | converter-bot: 2 | build: . 3 | container_name: converter-bot 4 | hostname: converter-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /converter-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.12 2 | -------------------------------------------------------------------------------- /deploy/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | ENV DOCKER_HOST unix:///var/run/docker.sock 4 | RUN apk add --update docker py-pip && pip install docker-compose && docker -v 5 | 6 | ADD . /go/src/github.com/umputun/rt-bot/deploy 7 | RUN \ 8 | cd /go/src/github.com/umputun/rt-bot/deploy && \ 9 | go get -v && \ 10 | go build -o /srv/deploy && \ 11 | rm -rf /go/src/* 12 | 13 | ADD deploy.sh /srv/deploy.sh 14 | 15 | EXPOSE 8080 16 | WORKDIR /srv 17 | CMD ["/srv/deploy"] 18 | -------------------------------------------------------------------------------- /deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | cd /srv/rt-bot 3 | # export DOCKER_HOST=unix:///var/run/docker.sock 4 | 5 | echo "deploy bots" 6 | /usr/bin/docker-compose ps 7 | /usr/bin/docker-compose pull 8 | /usr/bin/docker-compose up -d 9 | /usr/bin/docker-compose ps 10 | /usr/bin/docker images --no-trunc | grep none | awk "{print \$3}" | xargs /usr/bin/docker rmi 11 | echo "all done" 12 | -------------------------------------------------------------------------------- /docker-bot/COPYING: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | http://www.wtfpl.net/ 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. -------------------------------------------------------------------------------- /docker-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:2.4-rc-onbuild 2 | ADD Gemfile . 3 | ADD Gemfile.lock . 4 | ADD Rakefile . 5 | RUN bundle install 6 | RUN rake db:create 7 | EXPOSE "8080" 8 | CMD ["bundle", "exec", "puma", "-p", "8080", "-e", "production"] 9 | -------------------------------------------------------------------------------- /docker-bot/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | ruby "2.4.0" 3 | gem 'sinatra' 4 | gem 'daybreak' 5 | gem 'puma' 6 | gem 'rake' 7 | gem 'json' 8 | -------------------------------------------------------------------------------- /docker-bot/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | daybreak (0.3.0) 5 | json (2.0.2) 6 | puma (3.6.2) 7 | rack (1.6.5) 8 | rack-protection (1.5.3) 9 | rack 10 | rake (12.0.0) 11 | sinatra (1.4.7) 12 | rack (~> 1.5) 13 | rack-protection (~> 1.4) 14 | tilt (>= 1.3, < 3) 15 | tilt (2.0.5) 16 | 17 | PLATFORMS 18 | ruby 19 | 20 | DEPENDENCIES 21 | daybreak 22 | json 23 | puma 24 | rake 25 | sinatra 26 | 27 | RUBY VERSION 28 | ruby 2.4.0p0 29 | 30 | BUNDLED WITH 31 | 1.13.7 32 | -------------------------------------------------------------------------------- /docker-bot/README.md: -------------------------------------------------------------------------------- 1 | #Бот для чата [Радио-Т](https://chat.radio-t.com) 2 | 3 | ##Описание 4 | Если в чате кто-то жалуется на то, что ведущие слишком долго обсуждают одну из своих излюбленных тем, этот бот сообщит, сколько раз та или иная тема была упомянута в чате в ходе текущего выпуска. 5 | Изначально этот бот проектировался для подсчёта упоминаний слова "докер", но в последствии был доработан для того, чтобы понимать также и упоминание другой популярной темы для обсуждений. 6 | 7 | ## Примеры 8 | Сообщение: 9 | ```json 10 | { 11 | text: "Сколько можно про докер?", 12 | username: "test", 13 | display_name: "test" 14 | } 15 | ``` 16 | 17 | Ответ: 18 | ```json 19 | { 20 | bot: "docker-bot", 21 | text: "За текущий выпуск(№518) докер упоминали уже 1000 раз." 22 | } 23 | ``` 24 | 25 | Сообщение: 26 | ```json 27 | { 28 | text: "Сколько можно про apple?", 29 | username: "test", 30 | display_name: "test" 31 | } 32 | ``` 33 | 34 | Ответ: 35 | ```json 36 | { 37 | bot: "docker-bot", 38 | text: "За текущий выпуск(№518) apple упоминали уже 5000000 раз." 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /docker-bot/Rakefile: -------------------------------------------------------------------------------- 1 | namespace :db do 2 | 3 | require 'daybreak' 4 | 5 | task :create do 6 | puts 'Trying to create database...' 7 | db = Daybreak::DB.new "radio-t-docker-bot.db" 8 | if db["created_at"]==nil 9 | db["created_at"] = Time.now 10 | else 11 | puts "Database already created at #{db["created_at"]}" 12 | end 13 | db.flush 14 | db.close 15 | end 16 | 17 | end -------------------------------------------------------------------------------- /docker-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "docker-bot" 2 | ignored_commands: 3 | - "докер" 4 | - "шмокер" 5 | - "blah blah blah" 6 | test_cases: 7 | - command: "Сколько можно про докер?" 8 | result: "^За текущий выпуск\\(№\\d{3}\\) докер упоминали уже \\d+ раз.$" 9 | 10 | - command: "Сколько можно про Apple?" 11 | result: "^За текущий выпуск\\(№\\d{3}\\) Apple упоминали уже \\d+ раз.$" 12 | -------------------------------------------------------------------------------- /docker-bot/commands.rb: -------------------------------------------------------------------------------- 1 | class CommandHandler 2 | @@valid_commands = ['сколько можно про докер?', 3 | 'сколько можно про docker?', 4 | 'сколько можно про эппл?', 5 | 'сколько можно про apple?', 6 | ] 7 | 8 | def initialize(db, podcast) 9 | @db = db 10 | @podcast = podcast 11 | end 12 | 13 | def valid_commands 14 | return @@valid_commands 15 | end 16 | 17 | def exec(cmd) 18 | case cmd 19 | when 'сколько можно про докер?', 'сколько можно про docker?' 20 | count = @db.get_count(@podcast.get_current_podcast_number, 'docker') 21 | return "За текущий выпуск(№#{@podcast.get_current_podcast_number}) докер упоминали уже #{count} раз." 22 | when 'сколько можно про эппл?', 'сколько можно про apple?' 23 | count = @db.get_count(@podcast.get_current_podcast_number, 'apple') 24 | return "За текущий выпуск(№#{@podcast.get_current_podcast_number}) Apple упоминали уже #{count} раз." 25 | else 26 | return 'Так. Вы меня запутали.' 27 | end 28 | end 29 | end -------------------------------------------------------------------------------- /docker-bot/config.ru: -------------------------------------------------------------------------------- 1 | require './docker-bot' 2 | run Sinatra::Application -------------------------------------------------------------------------------- /docker-bot/db.rb: -------------------------------------------------------------------------------- 1 | require 'daybreak' 2 | 3 | class DatabaseHandler 4 | @@flush_period = 30 5 | 6 | def initialize 7 | @db = Daybreak::DB.new "radio-t-docker-bot.db" 8 | @last_flush_performed = Time.now 9 | end 10 | 11 | def add(podcast_number, word, word_count) 12 | if @db[podcast_number] == nil 13 | @db[podcast_number] = {} 14 | @db[podcast_number][word]=word_count 15 | elsif @db[podcast_number][word] == nil 16 | @db[podcast_number][word]=word_count 17 | else 18 | @db[podcast_number][word]+=word_count 19 | end 20 | if Time.now - @last_flush_performed > @@flush_period 21 | self.flush 22 | end 23 | end 24 | 25 | def get_count(podcast_number, word) 26 | begin 27 | count = @db[podcast_number][word] 28 | rescue 29 | count = 0 30 | end 31 | return count 32 | end 33 | 34 | def flush 35 | @db.flush 36 | end 37 | 38 | end -------------------------------------------------------------------------------- /docker-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | docker-bot: 2 | build: . 3 | ports: 4 | - "8080:8080" -------------------------------------------------------------------------------- /docker-bot/podcast.rb: -------------------------------------------------------------------------------- 1 | require 'rss' 2 | require 'open-uri' 3 | 4 | class PodcastHandler 5 | @@rss_feed_url = 'http://feeds.rucast.net/radio-t' 6 | def initialize 7 | @current_podcast_number = nil 8 | @last_time_podcast_number_was_successfully_detected = nil 9 | self.detect_current_podcast_number 10 | end 11 | 12 | def detect_current_podcast_number 13 | open(@@rss_feed_url) do |rss| 14 | feed = RSS::Parser.parse(rss, false) 15 | podcast_numbers = [] 16 | feed.items.each do |item| 17 | number = item.title.scan(/\d\d\d/).last.to_i 18 | podcast_numbers.push(number) 19 | end 20 | @current_podcast_number = podcast_numbers.max+1 21 | @last_time_podcast_number_was_successfully_detected = Time.now 22 | end 23 | end 24 | 25 | def get_current_podcast_number 26 | begin 27 | if Time.now.saturday? and Time.now - @last_time_podcast_number_was_successfully_detected > 60*60*24 28 | self.detect_current_podcast_number 29 | return @current_podcast_number 30 | else 31 | return @current_podcast_number 32 | end 33 | rescue 34 | return @current_podcast_number 35 | end 36 | end 37 | 38 | end -------------------------------------------------------------------------------- /docker-compose-deploy.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | 5 | deploy: 6 | build: deploy 7 | container_name: deploy 8 | hostname: deploy 9 | restart: always 10 | 11 | logging: 12 | driver: json-file 13 | options: 14 | max-size: "10m" 15 | max-file: "5" 16 | 17 | ports: 18 | - 1443:443 19 | 20 | environment: 21 | - DEPLOY_USER 22 | - DEPLOY_PASSWD 23 | volumes: 24 | - /var/run/docker.sock:/var/run/docker.sock 25 | - .:/srv/rt-bot 26 | - ./docker-compose.yml:/srv/docker-compose.yml 27 | - ./.env:/srv/.env 28 | -------------------------------------------------------------------------------- /doit-bot/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .idea 3 | npm-debug.log -------------------------------------------------------------------------------- /doit-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mhart/alpine-node:6 2 | WORKDIR /bot 3 | ADD . /bot 4 | RUN npm install 5 | EXPOSE 8080 6 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /doit-bot/README.md: -------------------------------------------------------------------------------- 1 | ![xQNBz0U.png](http://i.imgur.com/xQNBz0U.png) 2 | ### doit-bot для [ чата Радио-Т](https://chat.radio-t.com/) 3 | 4 | Бот отвечает на разные слова, цитируя Шaйа Лабaфa. Тем самым мотивирует участников на те или иные действия. 5 | Список заранее заданных слов и ответов на них в `trigger.json.` 6 | 7 | Для запуска достаточно: 8 | ``` 9 | $ docker-compose up 10 | ``` 11 | 12 | Ildar Gilfanov [@rabinzon](https://github.com/rabinzon). 13 | -------------------------------------------------------------------------------- /doit-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "doit-bot" 2 | 3 | defaults: 4 | username: "test-user" 5 | display_name: "Test User" 6 | 7 | ignored_commands: 8 | - "Привет" 9 | - "бобук" 10 | - "google" 11 | - "яндекс" 12 | - "..." 13 | - "добра всем" 14 | 15 | test_cases: 16 | - command: "хочу" 17 | result: "^@test-user (So just do it)$" 18 | 19 | - command: "просто сделай " 20 | result: "^@test-user (try it!)$" 21 | 22 | - command: "невозможно" 23 | result: "^@test-user (Nothing is impossible)$" 24 | 25 | - command: "я не могу" 26 | result: "^@test-user ((Nothing is impossible)|(Yes you can))" 27 | 28 | - command: "завтра" 29 | result: "^@test-user ((Yesterday you said tomorrow)|(Don't let your dreams be dreams)|(You should get to the point))$" 30 | -------------------------------------------------------------------------------- /doit-bot/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | doit-bot: 2 | build: . 3 | container_name: doit-bot 4 | hostname: doit-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /doit-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "doit-bot", 3 | "version": "0.0.1", 4 | "main": "index.js", 5 | "license": "ISC", 6 | "scripts": { 7 | "start": "nodemon index.js" 8 | }, 9 | "repository": "git@github.com:umputun/rt-bot.git", 10 | "author": "rabinzon ildarrazin@gmail.com", 11 | "dependencies": { 12 | "body-parser": "^1.15.2", 13 | "express": "^4.14.0", 14 | "nodemon": "^1.11.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /etc/ssl/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/etc/ssl/.keep -------------------------------------------------------------------------------- /excerpt-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | ADD . /go/src/github.com/umputun/excerpt-bot/excerpt 4 | RUN \ 5 | cd /go/src/github.com/umputun/excerpt-bot/excerpt && \ 6 | go get -v && \ 7 | go build -o /srv/excerpt && \ 8 | rm -rf /go/src/* 9 | 10 | EXPOSE 8080 11 | WORKDIR /srv 12 | CMD ["/srv/excerpt"] 13 | -------------------------------------------------------------------------------- /excerpt-bot/README.md: -------------------------------------------------------------------------------- 1 | # excerpt-bot - раскрывает ссылки на краткое описание 2 | 3 | Бот слушает все сообщения и отвечает на любые ссылки короткой версией текста по ссылке. 4 | -------------------------------------------------------------------------------- /excerpt-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "excerpt-bot" 2 | bot_display_name: "excerpt" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | - "http://aaa.bbb.com/aaa.png" 7 | 8 | test_cases: 9 | - command: "https://radio-t.com/p/2016/11/06/bot/" 10 | result: "^В выпуске 520 была озвучена идея.*" 11 | -------------------------------------------------------------------------------- /excerpt-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | excerpt-bot: 2 | build: . 3 | container_name: excerpt-bot 4 | hostname: sample-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /gif-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | RUN set -x && \ 4 | apk add --no-cache ca-certificates && \ 5 | rm -rf /var/cache/apk/* /tmp/* 6 | 7 | ADD . /go/src/github.com/umputun/rt-bot/gif-bot 8 | 9 | RUN \ 10 | cd /go/src/github.com/umputun/rt-bot/gif-bot && \ 11 | go build -o /srv/gif-bot && \ 12 | rm -rf /go/src/* 13 | 14 | EXPOSE 8080 15 | WORKDIR /srv 16 | CMD ["/srv/gif-bot"] -------------------------------------------------------------------------------- /gif-bot/README.md: -------------------------------------------------------------------------------- 1 | ## Радио-Т gif бот 2 | Простенький бот который отображает случайную gif картинку 3 | 4 | На данный момент пока только один источник - http://developerslife.ru/ 5 | 6 | ## Запрос 7 | ``` 8 | { 9 | "text" : "показать гифку", 10 | "username": "user", 11 | "display_name": "User name" 12 | } 13 | ``` 14 | 15 | ## Ответ 16 | ``` 17 | { 18 | "text": "[решил поставить сразу кучу брек поинтов, но баг всеравно проскакивает] \n![решил поставить сразу кучу брек поинтов, но баг всеравно проскакивает](http://static.devli.ru/public/images/gifs/201310/b3c2a84c-de49-4f9d-ac75-fe7b38682444.gif)", 19 | "bot": "gif-bot" 20 | } 21 | ``` -------------------------------------------------------------------------------- /gif-bot/_bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "gif-bot" 2 | 3 | ignored_commands: 4 | - "показать сиськи" 5 | 6 | test_cases: 7 | - command: "показать гифку" 8 | result: ".+" 9 | -------------------------------------------------------------------------------- /gif-bot/config.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | const ( 4 | BotId = "gif-bot" 5 | Port = "8080" 6 | MaxAttemps = 10 7 | UrlRandomItem = "http://developerslife.ru/random?json=true" 8 | BotAuthor = "Igor Yatsenko" 9 | BotDescription = "Бот генерирует случайную gif картинку" 10 | ) 11 | 12 | var BotCommands = []string{ 13 | "показать гифку", 14 | } 15 | -------------------------------------------------------------------------------- /gif-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | gif-bot: 2 | build: . 3 | container_name: gif-bot 4 | hostname: gif-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /gif-bot/request.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "io/ioutil" 7 | "log" 8 | "net/http" 9 | "strings" 10 | "time" 11 | ) 12 | 13 | type Request struct { 14 | Text string `json:"text"` 15 | Username string `json:"username"` 16 | DisplayName string `json:"display_name"` 17 | } 18 | 19 | func (req *Request) ParseData(r *http.Request) error { 20 | 21 | body, err := ioutil.ReadAll(r.Body) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | err = json.Unmarshal(body, &req) 27 | if err != nil { 28 | return err 29 | } 30 | 31 | req.LogRequest(r) 32 | return nil 33 | } 34 | 35 | func (req *Request) ParseText() (string, error) { 36 | 37 | if "" == req.Text { 38 | return "", errors.New("Empty request text") 39 | } 40 | 41 | if strings.HasPrefix(strings.ToLower(req.Text), "показать гифку") { 42 | return "random", nil 43 | } 44 | 45 | return "", errors.New("Unknown command") 46 | } 47 | 48 | func (req *Request) LogRequest(r *http.Request) { 49 | 50 | st := time.Now() 51 | log.Printf("%+v - %v - %s - %s", req.Username, time.Since(st), r.RemoteAddr, r.UserAgent()) 52 | } 53 | -------------------------------------------------------------------------------- /gif-bot/response.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | type Response struct { 8 | Text string `json:"text"` 9 | Bot string `json:"bot"` 10 | } 11 | 12 | func (r *Response) ToJson() ([]byte, error) { 13 | 14 | text, err := json.Marshal(r) 15 | if err != nil { 16 | return nil, err 17 | } 18 | return text, nil 19 | } 20 | -------------------------------------------------------------------------------- /giphy-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | 3 | RUN mkdir /usr/giphy-bot 4 | WORKDIR /usr/giphy-bot/ 5 | 6 | COPY requirements.txt /tmp/ 7 | RUN pip install -r /tmp/requirements.txt 8 | COPY main.py /usr/giphy-bot/ 9 | 10 | EXPOSE 8080 11 | 12 | CMD ["python", "main.py"] 13 | -------------------------------------------------------------------------------- /giphy-bot/README.md: -------------------------------------------------------------------------------- 1 | #Giphy 2 | 3 | Находит гифку (на самом деле - не гифку, а `.webp`) с помощью сервиса [Giphy](http://giphy.com/) и вставляет её в чат. 4 | 5 | Использует [Translate Endpoint](https://github.com/Giphy/GiphyAPI#translate-endpoint) из их API. 6 | 7 | Использует `fixed_height_small` версию картинки, чтобы не засорять чат. 8 | 9 | Отзывается на любое сообщение вида `giphy <запрос>` (case-insensitive). 10 | -------------------------------------------------------------------------------- /giphy-bot/_bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "giphy-bot" 2 | bot_display_name: "Giphy" 3 | 4 | ignored_commands: 5 | - "привет" 6 | - "как дела?" 7 | 8 | test_cases: 9 | - command: "giphy сиськи" 10 | result: ".+" 11 | -------------------------------------------------------------------------------- /giphy-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | giphy-bot: 2 | build: . 3 | container_name: giphy-bot 4 | hostname: giphy-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /giphy-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==1.1.2 2 | async-timeout==1.1.0 3 | chardet==2.3.0 4 | multidict==2.1.2 5 | yarl==0.7.0 6 | -------------------------------------------------------------------------------- /grabpage-bot/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | venv/ -------------------------------------------------------------------------------- /grabpage-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | 3 | RUN mkdir /usr/grabpage-bot 4 | WORKDIR /usr/grabpage-bot/ 5 | 6 | COPY requirements.txt /tmp/ 7 | RUN pip install -r /tmp/requirements.txt 8 | COPY main.py /usr/grabpage-bot/ 9 | 10 | EXPOSE 8080 11 | 12 | CMD ["python", "main.py"] 13 | -------------------------------------------------------------------------------- /grabpage-bot/README.md: -------------------------------------------------------------------------------- 1 | #Grabpage 2 | 3 | Находит ссылки в сообщении и отвечает в следующем сообщении ссылкой на скриншот размером 240 x 168. -------------------------------------------------------------------------------- /grabpage-bot/_bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "grabpage-bot" 2 | 3 | ignored_commands: 4 | - "Привет" 5 | - "Как дела?" 6 | 7 | test_cases: 8 | - command: "https://radio-t.com/p/2016/11/06/bot/" 9 | result: "\\n.+" 10 | -------------------------------------------------------------------------------- /grabpage-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | grabpage-bot: 2 | build: . 3 | container_name: grabpage-bot 4 | hostname: grabpage-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /grabpage-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==1.1.4 2 | async-timeout==1.1.0 3 | asyncio==3.4.3 4 | chardet==2.3.0 5 | multidict==2.1.2 6 | yarl==0.7.0 7 | -------------------------------------------------------------------------------- /guido-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | RUN pip install flask 3 | CMD echo -e "import this,re,flask,json,base64\na=flask.Flask(__name__)\ng64=b'IVtndWlkb10oaHR0cHM6Ly9wYnMudHdpbWcuY29tL3Byb2ZpbGVfaW1hZ2VzLzQyNDQ5NTAwNC9HdWlkb0F2YXRhcl80MDB4NDAwLmpwZykK'\ng=base64.b64decode(g64).decode('utf-8')\nz=''.join([this.d.get(c,c) for c in this.s])\nf_g=lambda s:re.search('.*?(guido|гвидо)',s,re.I) is not None\nm_a=lambda r:f_g(r.get('text','')) and r.get('username','')!='rt-bot'\ndef h():return (json.dumps({'text':g+z, 'bot': 'g-bot'}),201,{'content-type': 'application/json; charset=UTF-8'}) if m_a(flask.request.json) else ('',417)\na.route('/event',methods=['POST'])(h)\na.run('0.0.0.0',8080)"|python 4 | -------------------------------------------------------------------------------- /guido-bot/README.md: -------------------------------------------------------------------------------- 1 | # Guido bot 2 | 3 | ## Самый минималистичный бот 4 | Состоит из одного `Dockerfile` 5 | 6 | ## Что делает? 7 | Постит аватарку Гвидо и дзен Питона, каждый раз, когда встречает упоминание Гвидо. -------------------------------------------------------------------------------- /guido-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "guido-bot" 2 | bot_display_name: "g-bot" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | - "Как дела?" 7 | 8 | test_cases: 9 | - command: "гвидо" 10 | result: ".+" 11 | 12 | - command: "guido" 13 | result: ".+" 14 | -------------------------------------------------------------------------------- /guido-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | guido-bot: 2 | build: . 3 | container_name: guido-bot 4 | hostname: guido-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /hcalendar-bot/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible Node.js debug attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "program": "${workspaceRoot}\\app.js", 12 | "cwd": "${workspaceRoot}", 13 | "runtimeExecutable": "C:\\Program Files\\nodejs\\node.exe" 14 | }, 15 | { 16 | "type": "node", 17 | "request": "attach", 18 | "name": "Attach to Process", 19 | "port": 5858 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /hcalendar-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:argon 2 | 3 | # Create app directory 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | # Install app dependencies 8 | COPY package.json /usr/src/app/ 9 | RUN npm install 10 | 11 | # Bundle app source 12 | COPY . /usr/src/app 13 | 14 | EXPOSE 8080 15 | CMD [ "npm", "start" ] -------------------------------------------------------------------------------- /hcalendar-bot/README.md: -------------------------------------------------------------------------------- 1 | Hebrew calendar commands: 2 | **hcalendar** ==> show date of Hebrew Calendar 3 | -------------------------------------------------------------------------------- /hcalendar-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "hcalendar-bot" 2 | 3 | defaults: 4 | display_name: "hcalendar-bot" 5 | 6 | ignored_commands: 7 | - "Hi" 8 | 9 | test_cases: 10 | - command: "hi hcalendar" 11 | result: "hi" -------------------------------------------------------------------------------- /hcalendar-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | sovet-bot: 2 | build: . 3 | container_name: hcalendar-bot 4 | hostname: hcalendar-bot 5 | restart: hcalendar-bot 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /hcalendar-bot/formatting.js: -------------------------------------------------------------------------------- 1 | exports.FormatDay_v1 = function FormatDay_v1(hDay) { 2 | return FormatDay(hDay); 3 | } 4 | 5 | function FormatDay(hDay) 6 | { 7 | var hDayStr = hDay + "th"; 8 | if (hDay == 1) 9 | hDayStr = "1st"; 10 | if (hDay == 2) 11 | hDayStr = "2nd"; 12 | if (hDay == 3) 13 | hDayStr = "3rd"; 14 | if (hDay == 21) 15 | hDayStr = "21st"; 16 | if (hDay == 22) 17 | hDayStr = "22nd"; 18 | if (hDay == 23) 19 | hDayStr = "23rd"; 20 | if (hDay == 31) 21 | hDayStr = "31st"; 22 | if (hDay == 32) 23 | hDayStr = "32nd"; 24 | if (hDay == 33) 25 | hDayStr = "33rd"; 26 | if (hDay == 41) 27 | hDayStr = "41st"; 28 | if (hDay == 42) 29 | hDayStr = "42nd"; 30 | if (hDay == 43) 31 | hDayStr = "43rd"; 32 | return hDayStr; 33 | } 34 | -------------------------------------------------------------------------------- /hcalendar-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hcalendar-bot", 3 | "version": "0.0.1", 4 | "description": "bot 'HCalendar' for radio-t", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "node app.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "body-parser": "^1.15.2", 14 | "express": "^4.14.0", 15 | "request": "^2.78.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /hello/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM perl:5 2 | 3 | RUN cpanm Carton@v1.0.22 4 | 5 | ADD cpanfile /app/ 6 | ADD cpanfile.snapshot /app/ 7 | 8 | WORKDIR /app 9 | 10 | RUN carton install --deployment 11 | 12 | ADD cmd /app 13 | ADD app.psgi /app 14 | 15 | EXPOSE 8080 16 | 17 | CMD ./cmd 18 | -------------------------------------------------------------------------------- /hello/README.md: -------------------------------------------------------------------------------- 1 | # hello 2 | 3 | Очень простой бот. 4 | 5 | Если видит что-то похожее на приветствие, то отвечает в ответ. 6 | 7 | Пример сообщения на которое бот отвечает: 8 | 9 | $ curl \ 10 | -v \ 11 | -X POST \ 12 | -d '{"text":"Привет","username":123,"display_name":"login"}' \ 13 | http://docker:8080/event 14 | 15 | Бот отвечает статусом 201 и в ответе json: 16 | 17 | {"bot":"hello","text":"Hello!"} 18 | 19 | Пример сообщения на которое бот не знает что ответчать и отвечает статусом 417 20 | с пустым body: 21 | 22 | $ curl \ 23 | -v \ 24 | -X POST \ 25 | -d '{"text":"Sample text","username":123,"display_name":"login"}' \ 26 | http://docker:8080/event 27 | -------------------------------------------------------------------------------- /hello/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "hello" 2 | 3 | ignored_commands: 4 | - "Как дела?" 5 | 6 | test_cases: 7 | - command: "Привет" 8 | result: ".+" 9 | -------------------------------------------------------------------------------- /hello/build: -------------------------------------------------------------------------------- 1 | docker build --tag hello_bot . 2 | -------------------------------------------------------------------------------- /hello/cmd: -------------------------------------------------------------------------------- 1 | MOJO_MODE=production MOJO_LISTEN=http://*:8080 carton exec perl app.psgi daemon 2 | -------------------------------------------------------------------------------- /hello/cpanfile: -------------------------------------------------------------------------------- 1 | requires 'Mojolicious', '== 7.10'; 2 | -------------------------------------------------------------------------------- /hello/docker-compose.yml: -------------------------------------------------------------------------------- 1 | hello: 2 | build: . 3 | ports: 4 | - "8080:8080" 5 | -------------------------------------------------------------------------------- /hello/run: -------------------------------------------------------------------------------- 1 | docker run \ 2 | --rm \ 3 | --publish 8080:8080 \ 4 | hello_bot 5 | -------------------------------------------------------------------------------- /hello/update_deps: -------------------------------------------------------------------------------- 1 | time docker run \ 2 | --rm \ 3 | -it \ 4 | hello_bot \ 5 | sh -c 'cd /app; rm -rf cpanfile.snapshot local; carton install' 6 | -------------------------------------------------------------------------------- /karma-bot/.gitignore: -------------------------------------------------------------------------------- 1 | env/ 2 | __pycache__ 3 | *.pyc 4 | -------------------------------------------------------------------------------- /karma-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | MAINTAINER Sergey Levitin 3 | 4 | RUN mkdir /app 5 | WORKDIR /app 6 | 7 | RUN set -x && \ 8 | apk add --no-cache --virtual builddeps ca-certificates && \ 9 | rm -rf /var/cache/apk/* /tmp/* 10 | 11 | COPY ./requirements.txt /app/requirements.txt 12 | 13 | RUN set -x && \ 14 | pip install --no-cache-dir --disable-pip-version-check --upgrade pip && \ 15 | pip install --no-cache-dir --disable-pip-version-check -r requirements.txt 16 | 17 | COPY . /app 18 | 19 | RUN set -x \ 20 | ./run_tests.sh && \ 21 | find . -name '__pycache__' -type d | xargs rm -rf \ 22 | && python -c 'import compileall, os; compileall.compile_dir(os.curdir, force=1)' 23 | 24 | EXPOSE "8080" 25 | 26 | CMD ["gunicorn", "-b", "0.0.0.0:8080", "rt_karma_bot:app"] 27 | -------------------------------------------------------------------------------- /karma-bot/Makefile: -------------------------------------------------------------------------------- 1 | run: 2 | DEBUG=1 python rt_karma_bot.py 3 | 4 | clean: 5 | find . -name '*.pyc' -type f -delete 6 | find . -name '__pycache__' -type d | xargs rm -rf 7 | 8 | check: 9 | find . -name "*.py" -not -path "./env/*" | xargs flake8 10 | 11 | test: check 12 | ./run_tests.sh 13 | 14 | .PHONY: run clean check test 15 | -------------------------------------------------------------------------------- /karma-bot/README.md: -------------------------------------------------------------------------------- 1 | # Бот для кармы в чате 2 | 3 | С помощью этого бота можно ставить плюсадины и минусадины пользователям чатика, а также смотреть свою карму и карму других пользователей. 4 | 5 | ## Команды бота 6 | 7 | - `@bobuk++` - поставить +1 в карму Бобуку 8 | - `@umputun--` - поставить -1 Умпутуну 9 | - `/karma @umputun` - посмотреть карму Умпутуна 10 | - `/karma` посмотреть свою карму 11 | - `/karma-top 100` - показать топ 100 пользователей 12 | - `/karma-top` - показать топ 10 пользователей 13 | 14 | Нельзя изменять свою карму. Также, можно изменять карму конкретного пользователя не чаще, чем 1 раз в сутки. 15 | -------------------------------------------------------------------------------- /karma-bot/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/karma-bot/__init__.py -------------------------------------------------------------------------------- /karma-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "karma-bot" 2 | 3 | defaults: 4 | username: "test-user" 5 | display_name: "Test User" 6 | 7 | ignored_commands: 8 | - "Ignored message 1" 9 | - "Ignored message 2" 10 | - "Ignored message 3" 11 | 12 | test_cases: 13 | - command: "/karma selevit" 14 | result: "^Карма пользователя @selevit: \\d+.$" 15 | 16 | - command: 17 | username: "selevit" 18 | text: "selevit +1" 19 | result: "^Вы не можете изменять свою карму!$" 20 | 21 | - command: "/karma-top" 22 | result: "^Статистика кармы пользователей пуста.$" 23 | 24 | - command: "selevit++" 25 | result: "^Карма пользователя @selevit увеличена \\(текущее значение: \\d+\\).$" 26 | 27 | - command: "/karma-top 0" 28 | result: "^Количество пользователей в /karma top \\[n\\] должно быть > 0.$" 29 | 30 | - command: "/karma-top 10" 31 | result: "^Топ 1 пользователей:\\\\n\\\\n- selevit: 1\\\\n$" 32 | -------------------------------------------------------------------------------- /karma-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | karma-bot-storage: 5 | image: redis:3-alpine 6 | container_name: karma-bot-storage 7 | hostname: karma-bot-storage 8 | restart: always 9 | 10 | karma-bot: 11 | build: . 12 | container_name: karma-bot 13 | hostname: karma-bot 14 | restart: always 15 | ports: 16 | - "8080:8080" 17 | environment: 18 | - REDIS_HOST=karma-bot-storage 19 | depends_on: 20 | - karma-bot-storage 21 | -------------------------------------------------------------------------------- /karma-bot/requirements.in: -------------------------------------------------------------------------------- 1 | Flask 2 | redis 3 | mockredispy 4 | gunicorn 5 | flake8 6 | -------------------------------------------------------------------------------- /karma-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile --output-file requirements.txt requirements.in 6 | # 7 | click==6.6 # via flask 8 | configparser==3.5.0 # via flake8 9 | enum34==1.1.6 # via flake8 10 | flake8==3.0.4 11 | Flask==0.11.1 12 | gunicorn==19.6.0 13 | itsdangerous==0.24 # via flask 14 | Jinja2==2.8 # via flask 15 | MarkupSafe==0.23 # via jinja2 16 | mccabe==0.5.2 # via flake8 17 | mockredispy==2.9.3 18 | pycodestyle==2.0.0 # via flake8 19 | pyflakes==1.2.3 # via flake8 20 | redis==2.10.5 21 | Werkzeug==0.11.11 # via flask 22 | -------------------------------------------------------------------------------- /karma-bot/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | python -m unittest discover "$DIR/tests" 6 | -------------------------------------------------------------------------------- /karma-bot/settings.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | BOT_NAME = 'karma-bot' 5 | BOT_DESCRIPTION = 'Бот позволяет изменять карму пользователей чата' 6 | AUTHOR = 'Sergey Levitin ' 7 | 8 | REDIS_HOST = os.environ.get('REDIS_HOST', 'localhost') 9 | REDIS_PORT = int(os.environ.get('REDIS_PORT', 6379)) 10 | REDIS_DB = int(os.environ.get('REDIS_DB', 0)) 11 | 12 | LISTEN_HOST = os.environ.get('LISTEN_HOST', '0.0.0.0') 13 | LISTEN_PORT = int(os.environ.get('LISTEN_PORT', 8080)) 14 | 15 | DEBUG = bool(os.environ.get('DEBUG', False)) 16 | -------------------------------------------------------------------------------- /ksenks-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM strayge/alpine-py3-numpy-scipy 2 | 3 | RUN set -x && \ 4 | apk add --update --no-cache ffmpeg && \ 5 | rm -rf /var/cache/apk/* /tmp/* 6 | 7 | COPY requirements.txt /tmp/ 8 | 9 | RUN pip3 install --no-cache-dir --disable-pip-version-check -r /tmp/requirements.txt 10 | 11 | RUN mkdir /usr/ksenks-bot/ 12 | COPY . /usr/ksenks-bot/ 13 | WORKDIR /usr/ksenks-bot/ 14 | 15 | EXPOSE 8080 16 | 17 | CMD ["python3", "-u", "main.py"] 18 | -------------------------------------------------------------------------------- /ksenks-bot/README.md: -------------------------------------------------------------------------------- 1 | # ksenks-bot 2 | 3 | Пишет в чат время с последней активности Ксюши в эфире. 4 | 5 | ## Команды 6 | 7 | - Ксюша! 8 | - Ksenks! 9 | -------------------------------------------------------------------------------- /ksenks-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "ksenks-bot" 2 | 3 | defaults: 4 | username: "ksenks-bot" 5 | display_name: "ksenks-bot" 6 | 7 | ignored_commands: 8 | - "Привет" 9 | - "Где ксюша?" 10 | - "Ksenks! 123" 11 | 12 | test_cases: 13 | - command: "Ксюша!" 14 | result: ".+" 15 | 16 | - command: "ksenks!" 17 | result: ".+" 18 | 19 | - command: "КсЮшА!" 20 | result: ".+" -------------------------------------------------------------------------------- /ksenks-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | ksenks-bot: 2 | build: . 3 | container_name: ksenks-bot 4 | hostname: ksenks-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /ksenks-bot/log_handler.py: -------------------------------------------------------------------------------- 1 | from logging import Handler 2 | 3 | 4 | class ArrayHandler(Handler): 5 | def __init__(self, max_count=20): 6 | self.records = [] 7 | self.max_count = max_count 8 | Handler.__init__(self) 9 | 10 | def emit(self, record): 11 | try: 12 | msg = self.format(record) 13 | self.records.append(msg) 14 | if len(self.records) > self.max_count: 15 | del(self.records[0]) 16 | except Exception: 17 | self.handleError(record) 18 | 19 | def logs(self): 20 | return self.records 21 | -------------------------------------------------------------------------------- /ksenks-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==2.3.10 2 | pytz 3 | -------------------------------------------------------------------------------- /ksenks-bot/svm_model.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/ksenks-bot/svm_model.pickle -------------------------------------------------------------------------------- /ksenks-bot/timeout.py: -------------------------------------------------------------------------------- 1 | import signal 2 | 3 | 4 | class Timeout: 5 | """ 6 | http://stackoverflow.com/a/22348885 7 | Unix-only 8 | Examle of using: 9 | with timeout(seconds=3): 10 | time.sleep(4) 11 | """ 12 | def __init__(self, seconds=1, error_message='Timeout'): 13 | self.seconds = seconds 14 | self.error_message = error_message 15 | 16 | def handle_timeout(self, signum, frame): 17 | raise TimeoutError(self.error_message) 18 | 19 | def __enter__(self): 20 | signal.signal(signal.SIGALRM, self.handle_timeout) 21 | signal.alarm(self.seconds) 22 | 23 | def __exit__(self, type, value, traceback): 24 | signal.alarm(0) 25 | -------------------------------------------------------------------------------- /loro-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | 3 | COPY requirements.txt /tmp/ 4 | 5 | RUN pip install -r /tmp/requirements.txt 6 | RUN mkdir /usr/loro-bot 7 | COPY . /usr/loro-bot 8 | WORKDIR /usr/loro-bot 9 | 10 | EXPOSE 8080 11 | 12 | CMD ["gunicorn", "--bind", "0.0.0.0:8080", "wsgi:app"] 13 | -------------------------------------------------------------------------------- /loro-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "loro-bot" 2 | bot_display_name: "Loro" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | - "Как дела?" 7 | 8 | test_cases: 9 | - command: "Loro bobuk" 10 | result: ".+" 11 | 12 | - command: "Loro umputun" 13 | result: ".+" 14 | 15 | - command: "Loro trump" 16 | result: ".+" 17 | -------------------------------------------------------------------------------- /loro-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | loro-bot: 2 | build: . 3 | container_name: loro-bot 4 | hostname: loro-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /loro-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.11.1 2 | markovify==0.4.3 3 | gunicorn==19.6.0 4 | -------------------------------------------------------------------------------- /loro-bot/wsgi.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from bot import start_app 4 | 5 | app = start_app() -------------------------------------------------------------------------------- /lucky/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | ADD . /go/src/github.com/umputun/rt-bot/lucky 4 | RUN \ 5 | cd /go/src/github.com/umputun/rt-bot/lucky && \ 6 | go get -v && \ 7 | go build -o /srv/lucky && \ 8 | rm -rf /go/src/* 9 | 10 | EXPOSE 8080 11 | WORKDIR /srv 12 | CMD ["/srv/lucky"] 13 | -------------------------------------------------------------------------------- /lucky/README.md: -------------------------------------------------------------------------------- 1 | # Радио-Т Lucky bot 2 | https://github.com/umputun/rt-bot 3 | 4 | ### Описание 5 | Данный бот помогает разыгрывать подарки в прямом эфире Радио-Т 6 | 7 | Ведущий пишет 'lucky start' и все желающие получить подарок пишут 'хочу', после этого ведущий пишет 'lucky stop' и случайным выбором из всех участников определяется победитель. 8 | 9 | ### Команды 10 | 11 | `lucky start` - Начать прием заявок. Доступно только для ведущих ^(umputun|bobuk|grayru|ksenks)$ 12 | 13 | `lucky stop` - Остановить прием заявок и пределить победителя. Доступно только для ведущих ^(umputun|bobuk|grayru|ksenks)$ 14 | 15 | `lucky status` - Текущий статус розыгрыша 16 | 17 | `хочу` - Участвовать в розыгрыше, если прием заявок начат -------------------------------------------------------------------------------- /lucky/bot-spec.yml: -------------------------------------------------------------------------------- 1 | defaults: 2 | username: "test" 3 | display_name: "Test" 4 | 5 | bot_name: "lucky" 6 | 7 | ignored_commands: 8 | - "hello" 9 | - "lucky" 10 | 11 | test_cases: 12 | - command: 13 | text: "lucky start" 14 | username: "umputun" 15 | result: "Заявки на учатие в розыгрыше принимаются, пишем 'Хочу', голоса учитываются один раз" 16 | 17 | - command: 18 | text: "хочу" 19 | username: "test" 20 | result: "Заявка от участника \"test\" принята!" 21 | 22 | - command: 23 | text: "lucky stop" 24 | username: "umputun" 25 | result: "Розыгрыш завершен, учавствовали 1. Наш победитель \"test\", поздравляем!" 26 | -------------------------------------------------------------------------------- /lucky/docker-compose.yml: -------------------------------------------------------------------------------- 1 | lucky: 2 | build: . 3 | container_name: lucky 4 | hostname: lucky 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /memberberries/Controllers/EventController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using memberberries.Models; 3 | using memberberries.Services; 4 | 5 | namespace memberberries.Controllers 6 | { 7 | [Route("[controller]")] 8 | public class EventController : Controller 9 | { 10 | private readonly IBot _bot; 11 | public EventController(IBot bot) 12 | { 13 | _bot = bot; 14 | } 15 | 16 | // POST api/values 17 | [HttpPost] 18 | public IActionResult Post([FromBody] Message message) 19 | { 20 | var answer = _bot.GetAnswere(message); 21 | 22 | if (answer == null) { 23 | HttpContext.Response.StatusCode = 417; 24 | return new JsonResult(""); 25 | } 26 | 27 | HttpContext.Response.StatusCode = 201; 28 | 29 | return new JsonResult(answer); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /memberberries/Controllers/InfoController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using memberberries.Models; 3 | using memberberries.Services; 4 | 5 | namespace memberberries.Controllers 6 | { 7 | [Route("[controller]")] 8 | public class InfoController : Controller 9 | { 10 | private readonly IBot _bot; 11 | public InfoController(IBot bot) 12 | { 13 | _bot = bot; 14 | } 15 | 16 | // Get 17 | [HttpGet] 18 | public IActionResult Get() 19 | { 20 | return Ok(_bot.GetAbout()); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /memberberries/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:1.1-sdk-projectjson 2 | 3 | ENV ASPNETCORE_ENVIRONMENT Production 4 | 5 | RUN mkdir /app 6 | WORKDIR /app 7 | COPY ./project.json /app 8 | RUN dotnet restore 9 | COPY . /app 10 | RUN dotnet build 11 | 12 | EXPOSE 8080/tcp 13 | 14 | CMD ["dotnet", "run", "--server.urls", "http://*:8080"] 15 | -------------------------------------------------------------------------------- /memberberries/Models/About.cs: -------------------------------------------------------------------------------- 1 | namespace memberberries.Models 2 | { 3 | public class About 4 | { 5 | public string author { get; set; } 6 | 7 | public string info { get; set; } 8 | 9 | public string commands { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /memberberries/Models/Answer.cs: -------------------------------------------------------------------------------- 1 | namespace memberberries.Models 2 | { 3 | public class Answer 4 | { 5 | public string text { get; set; } 6 | 7 | public string bot { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /memberberries/Models/Message.cs: -------------------------------------------------------------------------------- 1 | namespace memberberries.Models 2 | { 3 | public class Message 4 | { 5 | public string text { get; set; } 6 | 7 | public string username { get; set; } 8 | 9 | public string display_name {get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /memberberries/Program.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.Extensions.Configuration; 5 | 6 | namespace memberberries 7 | { 8 | public class Program 9 | { 10 | public static void Main(string[] args) 11 | { 12 | var config = new ConfigurationBuilder() 13 | .AddCommandLine(args) 14 | .AddEnvironmentVariables(prefix: "ASPNETCORE_") 15 | .Build(); 16 | 17 | var host = new WebHostBuilder() 18 | .UseKestrel() 19 | .UseConfiguration(config) 20 | .UseContentRoot(Directory.GetCurrentDirectory()) 21 | .UseStartup() 22 | .Build(); 23 | 24 | host.Run(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /memberberries/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:8080/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": false, 14 | "launchUrl": "", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "memberberries": { 20 | "commandName": "Project", 21 | "launchBrowser": false, 22 | "launchUrl": "", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /memberberries/README.md: -------------------------------------------------------------------------------- 1 | # Member Berries 2 | Радио-Т бот-вспоминашка по мотивам 20 сезона сериала Южный Парк. 3 | 4 | ## Запрос 5 | ``` 6 | $ curl -H "Content-type: application/json" -X POST http://localhost:8080/event -d \ 7 | '{ 8 | "text" : "Помните Оляпку?", 9 | "id": 1024, 10 | "display_name": "User Name" 11 | }' 12 | ``` 13 | 14 | ## Ответ 15 | ``` 16 | { 17 | "text": "О! Я помню...", 18 | "bot": "MemberBerries" 19 | } 20 | ``` -------------------------------------------------------------------------------- /memberberries/Services/IBot.cs: -------------------------------------------------------------------------------- 1 | using memberberries.Models; 2 | 3 | namespace memberberries.Services 4 | { 5 | public interface IBot 6 | { 7 | Answer GetAnswere(Message message); 8 | 9 | About GetAbout(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /memberberries/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /memberberries/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "memberberries" 2 | bot_display_name: "MemberBerries" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | 7 | test_cases: 8 | - command: "Помните Оляпку?" 9 | result: "О! Я помню..." 10 | -------------------------------------------------------------------------------- /memberberries/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | rt-bot-memberberries: 5 | build: . 6 | container_name: rt-bot-memberberries 7 | ports: 8 | - "8080:8080" -------------------------------------------------------------------------------- /money-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:7-alpine 2 | MAINTAINER Serhiy Mytrovtsiy 3 | 4 | ENV NODE_PATH=.:/usr/lib/node_modules:/node_modules 5 | 6 | RUN set -x && \ 7 | npm install --silent -g nodemon mocha && \ 8 | mkdir -p /node_modules 9 | 10 | COPY ./package.json /package.json 11 | RUN npm install --silent --prefix / 12 | 13 | 14 | COPY ./currency.json /currency.json 15 | COPY ./app.js /app.js 16 | 17 | EXPOSE 8080 18 | CMD ["node", "/app.js"] 19 | -------------------------------------------------------------------------------- /money-bot/README.md: -------------------------------------------------------------------------------- 1 | # Бот для чата [Радио-Т](https://github.com/umputun/rt-bot) 2 | 3 | ## Описание 4 | Если в чате была упомянута какая-то валюта например 110$ или $110, бот конвертирует ее в евро, гривнях, рублях и белорусских рублях. 5 | 6 | ## Пример 7 | Сообщение: 8 | ```json 9 | { 10 | text: "а на digital ocean такой сервер стоит 5 евро", 11 | username: "test", 12 | display_name: "test" 13 | } 14 | ``` 15 | 16 | Ответ: 17 | @test упомянул 5 EUR 18 | 19 | 20 | | EUR | 5 | Курсы | 21 | |:-------------:|:--------------:|:---------------:| 22 | | USD | 5.32 | 1.06 | 23 | | UAH | 147.21 | 29.44 | 24 | | RUB | 317.15 | 63.43 | 25 | | BYN | 10.34 | 2.07 | 26 | 27 | [Оригинальный репозиторий](https://github.com/exelban/money-bot) 28 | -------------------------------------------------------------------------------- /money-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "money-bot" 2 | 3 | bot_display_name: "money-bot" 4 | 5 | defaults: 6 | username: "user" 7 | display_name: "User" 8 | 9 | ignored_commands: 10 | - "100 миллионов миллиардов" 11 | - "100 тысяч" 12 | - "123к тугриков" 13 | - "message with $ and with 100 123k" 14 | - "word $word word$ word" 15 | 16 | test_cases: 17 | - command: "а на digital ocean такой сервер стоит 5 евро" 18 | result: "@user упомянул 5 EUR.*" 19 | - command: "5$ бобук" 20 | result: "@user упомянул 5 USD.+" 21 | - command: "5 миллионов долларов" 22 | result: "@user упомянул 5 000 000 USD.+" 23 | - command: "5к баксов" 24 | result: "@user упомянул 5 000 USD.+" 25 | - command: "usd 5 000 000.51" 26 | result: "@user упомянул 5 000 000\\.51 USD.*" 27 | - command: "₽42к" 28 | result: "@user упомянул 42 000 RUB.*" 29 | - command: "5К $" 30 | result: "@user упомянул 5 000 USD.+" 31 | -------------------------------------------------------------------------------- /money-bot/currency.json: -------------------------------------------------------------------------------- 1 | {"USD_EUR":0.85888517,"USD_UAH":25.785,"USD_RUB":59.9145,"USD_BYN":1.9301,"USD_BTC":0.00036131,"EUR_USD":1.1642999960052867,"EUR_UAH":30.021475396996316,"EUR_RUB":69.75845211065874,"EUR_BYN":2.2472154222898038,"EUR_BTC":0.0004206732315566702,"UAH_USD":0.03878223773511732,"UAH_EUR":0.03330948885010665,"UAH_RUB":2.3236183827806864,"UAH_BYN":0.07485359705254993,"UAH_BTC":0.000014012410316075239,"RUB_USD":0.016690450558712832,"RUB_EUR":0.014335180465496665,"RUB_UAH":0.43036326765641036,"RUB_BYN":0.03221423862337164,"RUB_BTC":0.000006030426691368534,"BYN_USD":0.5181078700585462,"BYN_EUR":0.44499516605357237,"BYN_UAH":13.359411429459614,"BYN_RUB":31.042173980622763,"BYN_BTC":0.00018719755453085334,"BTC_USD":2767.706401704907,"BTC_EUR":2377.141983338407,"BTC_UAH":71365.30956796103,"BTC_RUB":165825.74520494865,"BTC_BYN":5341.950125930641} 2 | -------------------------------------------------------------------------------- /money-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | node: 2 | build: . 3 | ports: 4 | - "8080:8080" 5 | log_driver: "json-file" 6 | log_opt: 7 | max-size: "5m" 8 | max-file: "10" 9 | restart: always 10 | -------------------------------------------------------------------------------- /money-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "money-bot", 3 | "version": "0.1.0", 4 | "private": false, 5 | "dependencies": { 6 | "body-parser": "~1.15.2", 7 | "express": "~4.14.0", 8 | "async": "~2.1.4", 9 | "request": "~2.79.0", 10 | "node-cron": "*", 11 | "fs": "0.0.1-security" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /noter-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM anapsix/alpine-java:8_jdk 2 | 3 | ENV M2_HOME=/usr/lib/mvn 4 | ENV M2=$M2_HOME/bin 5 | ENV PATH $PATH:$JAVA_HOME:$JAVA:$M2_HOME:$M2 6 | 7 | ADD http://ftp.fau.de/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz /tmp 8 | 9 | RUN set -x && \ 10 | tar -xvzf /tmp/apache-maven-3.3.9-bin.tar.gz -C /tmp && \ 11 | mv /tmp/apache-maven-3.3.9 /usr/lib/mvn && \ 12 | rm -rf /tmp/* 13 | 14 | RUN mkdir bot 15 | ADD src /bot/src 16 | ADD pom.xml /bot 17 | 18 | RUN set -x && \ 19 | cd /bot && \ 20 | mvn install -q dependency:copy-dependencies && \ 21 | mv target/dependency . && \ 22 | mv target/bot.jar . && \ 23 | rm -r target src pom.xml /usr/lib/mvn 24 | 25 | WORKDIR /bot 26 | 27 | EXPOSE 8080 28 | 29 | CMD ["java", "-cp", "bot.jar:./dependency/*:.", "com.gekoreed.Server"] -------------------------------------------------------------------------------- /noter-bot/README.md: -------------------------------------------------------------------------------- 1 | # Noter bot 2 | Записать какую-то штуку привязаную к таймингу подкаста, например "Вот тут Бобук пошутил о фотоаппаратах" 3 | 4 | ## Запрос 5 | ``` 6 | { 7 | "text" : "sbot note Вот тут Бобук про фотоаппараты", 8 | "username": "rt", 9 | "display_name": "rt" 10 | } 11 | ``` 12 | 13 | ## Ответ 14 | ``` 15 | { 16 | "text": "saved", 17 | "bot": "sbot" 18 | } 19 | ``` 20 | После этого в любой момент можно сказать 21 | ## Запрос 22 | ``` 23 | { 24 | "text" : "sbot list", 25 | "username": "rt", 26 | "display_name": "rt" 27 | } 28 | ``` 29 | На что прийдет ответ типа 30 | "0:23:45 - Вот тут Бобук пошутил про фотоаппараты" -------------------------------------------------------------------------------- /noter-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "noter-bot" 2 | bot_display_name: "sbot" 3 | 4 | defaults: 5 | username: "test" 6 | 7 | ignored_commands: 8 | - "Привет" 9 | 10 | test_cases: 11 | - command: "sbot list" 12 | result: "Your story is empty" 13 | 14 | - command: "sbot note Вот тут Бобук пошутил про фотоаппараты" 15 | result: "### test, сохранено$" 16 | 17 | - command: "sbot list" 18 | result: "### Вот твоя история, test\n.+Вот тут Бобук пошутил про фотоаппараты" 19 | 20 | - command: "sbot clear" 21 | result: "^### Твоя история пуста, test$" 22 | -------------------------------------------------------------------------------- /noter-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | saver: 2 | build: . 3 | ports: 4 | - "8080:8080" -------------------------------------------------------------------------------- /noter-bot/src/main/java/com/gekoreed/entity/ChatRequest.java: -------------------------------------------------------------------------------- 1 | package com.gekoreed.entity; 2 | 3 | public class ChatRequest { 4 | public String text; 5 | public String username; 6 | public String display_name; 7 | 8 | public boolean startMessage() { 9 | return (display_name.equalsIgnoreCase("радио-т бот") 10 | || username.equalsIgnoreCase("радио-т бот")) 11 | && text.contains("Официальный кат!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /noter-bot/src/main/java/com/gekoreed/entity/Response.java: -------------------------------------------------------------------------------- 1 | package com.gekoreed.entity; 2 | 3 | public class Response { 4 | public String text; 5 | public String bot = "sbot"; 6 | 7 | public Response(String s) { 8 | this.text = s; 9 | } 10 | 11 | public static Response podcastStarted() { 12 | return new Response("Начинаю записывать заметки с этого момента."); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /or-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | 3 | COPY requirements.txt /tmp/ 4 | RUN pip install -r /tmp/requirements.txt 5 | 6 | RUN mkdir /usr/or-bot 7 | COPY . /usr/or-bot/ 8 | WORKDIR /usr/or-bot/ 9 | 10 | EXPOSE 8080 11 | 12 | CMD ["python", "main.py"] 13 | -------------------------------------------------------------------------------- /or-bot/README.md: -------------------------------------------------------------------------------- 1 | # OR-BOT 2 | 3 | Бот поможет узнать что или кто лучше и больше у вас не будет проблем с выбором. 4 | 5 | Примеры: 6 | ```buildoutcfg 7 | что лучше, морковка или салат? 8 | кто лучше, я или он или они 9 | что лучше, python или go или все хороши? 10 | кто лучше, Саша или Маша 11 | ``` 12 | -------------------------------------------------------------------------------- /or-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "or-bot" 2 | bot_display_name: "or-bot" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | - "Как дела?" 7 | 8 | test_cases: 9 | - command: "что лучше, этот или тот?" 10 | result: ".+" 11 | 12 | - command: "кто лучше, я или он" 13 | result: ".+" 14 | -------------------------------------------------------------------------------- /or-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | or-bot: 2 | build: . 3 | container_name: or-bot 4 | hostname: or-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /or-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | Flask==0.12 2 | -------------------------------------------------------------------------------- /random-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | ADD . /bot/ 4 | WORKDIR /bot 5 | RUN go build -o bot 6 | 7 | EXPOSE 8080 8 | CMD ["/bot/bot"] 9 | -------------------------------------------------------------------------------- /random-bot/README.md: -------------------------------------------------------------------------------- 1 | ### random-bot для [ чата Радио-Т](https://chat.radio-t.com/) 2 | Возвращает рандомное число или элемент списка. Вместе с ответом приходит рандомная строчка. 3 | Пример ответа: `Я принял решение: 12.` Если не повезет, бот может не ответить, сославшись на занятость. 4 | 5 | Пример комманд: 6 | `/random` - число от 0 до 100 7 | `/random min max` - число от min до max 8 | `/random Umputun Ksenks Gray Bobuk` - например Ksenks 9 | `/random да нет` - да или нет 10 | 11 | Ildar Gilfanov [@rabinzon](https://github.com/rabinzon). 12 | -------------------------------------------------------------------------------- /random-bot/answers.json: -------------------------------------------------------------------------------- 1 | [ 2 | "Вот так", 3 | "Я принял решение", 4 | "Мои решения не обсуждаются", 5 | "Ты меня спросил? я ответил", 6 | "Ха", 7 | "Случайность? не думаю", 8 | "Неудачник", 9 | "Чего надо? проваливай, я занят.", 10 | "Доверься мне", 11 | "Слово мое закон", 12 | "Не вздумай ослушаться", 13 | "Все плохо...", 14 | "Делай что задумал", 15 | "Да свершится предначертанное", 16 | "Хороший выбор", 17 | "Cосредоточься на своем вопросе, мысленно произнеси его...", 18 | "Любое утверждение ложно. это тоже", 19 | "От судьбы не уйдешь", 20 | "Да будет так", 21 | "Ты меня уже забодал", 22 | "Получай", 23 | "Если вы не оставите меня в покое, я превращу вас в безмозглую овцу", 24 | "Хватит тратить ману, на всякую чепуху", 25 | "Cлучайности не случайны" 26 | ] 27 | -------------------------------------------------------------------------------- /random-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "random-bot" 2 | 3 | defaults: 4 | username: "test-user" 5 | display_name: "Test User" 6 | 7 | ignored_commands: 8 | - "Привет" 9 | - "бобук" 10 | - "google" 11 | - "яндекс" 12 | - "..." 13 | - "добра всем" 14 | 15 | test_cases: 16 | - command: "/random Да Нет" 17 | result: "(.+:\\s(Да|Нет))|(Чего надо\\? проваливай, я занят\\.)" 18 | 19 | - command: "/random Umputun Ksenks Gray Bobuk" 20 | result: "(.+:\\s(Umputun|Ksenks|Gray|Bobuk))|(Чего надо\\? проваливай, я занят\\.)" 21 | 22 | - command: "/random" 23 | result: "(.+:\\s\\d+)|(Чего надо\\? проваливай, я занят\\.)" 24 | 25 | - command: "/random 1" 26 | result: "(.+:\\s1)|(Чего надо\\? проваливай, я занят\\.)" 27 | -------------------------------------------------------------------------------- /random-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | random-bot: 2 | build: . 3 | container_name: random-bot 4 | hostname: random-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /random-bot/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "testing" 5 | "regexp" 6 | ) 7 | 8 | func TestGetRandom(t *testing.T) { 9 | result := GetRandom("Да Нет") 10 | match, _ := regexp.MatchString("^((Да)|(Нет))", result) 11 | if !match { 12 | t.Error("should return random value") 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /rest-voter/.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | 14 | .idea 15 | 16 | .gradle 17 | 18 | build -------------------------------------------------------------------------------- /rest-voter/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8 2 | 3 | RUN mkdir /rest-voter 4 | 5 | COPY . /rest-voter 6 | 7 | WORKDIR /rest-voter 8 | 9 | RUN chmod 777 /rest-voter/gradlew 10 | 11 | EXPOSE 8080 12 | 13 | RUN ./gradlew build 14 | 15 | CMD ["./gradlew", "bootRun"] -------------------------------------------------------------------------------- /rest-voter/README.md: -------------------------------------------------------------------------------- 1 | # rest-voter 2 | 3 | Создание пользовательских голосований 4 | 5 | ## Команды 6 | 7 | - !голосование Ваш вопрос? Вариант ответа 1, Вариант 2, Вариант 3 8 | - !голосую ID_голосования Вариант_ответа 9 | - !результат ID_голосования -------------------------------------------------------------------------------- /rest-voter/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "rest-voter" 2 | 3 | defaults: 4 | username: "rest-voter" 5 | display_name: "rest-voter" 6 | 7 | ignored_commands: 8 | - "Привет" 9 | - "время" 10 | - "Подскажите номер выпуска" 11 | 12 | test_cases: 13 | - command: "!голосование кто станет презедентом? я, ты" 14 | result: ".+" -------------------------------------------------------------------------------- /rest-voter/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.0.5-2' 3 | ext.spring_boot_version = '1.4.2.RELEASE' 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 9 | classpath "org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version" 10 | } 11 | } 12 | 13 | 14 | apply plugin: 'idea' 15 | apply plugin: 'kotlin' 16 | apply plugin: 'application' 17 | apply plugin: 'org.springframework.boot' 18 | 19 | jar { 20 | baseName = 'rest-voter' 21 | version = '0.1.0' 22 | } 23 | 24 | springBoot { 25 | mainClass = 'ru.hixon.Application' 26 | } 27 | 28 | repositories { 29 | jcenter() 30 | } 31 | 32 | dependencies { 33 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 34 | compile "org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE" 35 | compile "org.springframework.boot:spring-boot-devtools" 36 | compile "com.fasterxml.jackson.module:jackson-module-kotlin:2.8.4" 37 | testCompile 'junit:junit' 38 | } 39 | 40 | task wrapper(type: Wrapper) { 41 | gradleVersion = '2.13' 42 | } -------------------------------------------------------------------------------- /rest-voter/docker-compose.yml: -------------------------------------------------------------------------------- 1 | rest-voter: 2 | build: . 3 | ports: 4 | - "8080:8080" -------------------------------------------------------------------------------- /rest-voter/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/rest-voter/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /rest-voter/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Nov 17 00:51:59 MSK 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip 7 | -------------------------------------------------------------------------------- /rest-voter/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'rest-voter' -------------------------------------------------------------------------------- /rest-voter/src/main/kotlin/ru/hixon/Application.kt: -------------------------------------------------------------------------------- 1 | package ru.hixon 2 | 3 | import com.fasterxml.jackson.module.kotlin.KotlinModule 4 | import org.springframework.boot.SpringApplication 5 | import org.springframework.boot.autoconfigure.SpringBootApplication 6 | import org.springframework.context.annotation.Bean 7 | import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder 8 | 9 | @SpringBootApplication 10 | open class Application { 11 | 12 | @Bean 13 | open fun objectMapperBuilder(): Jackson2ObjectMapperBuilder 14 | = Jackson2ObjectMapperBuilder().modulesToInstall(KotlinModule()) 15 | .featuresToEnable(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES) 16 | 17 | 18 | companion object { 19 | @JvmStatic fun main(args: Array) { 20 | SpringApplication.run(Application::class.java, *args) 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /rest-voter/src/main/kotlin/ru/hixon/domain/InfoResponse.kt: -------------------------------------------------------------------------------- 1 | package ru.hixon.domain 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | 5 | /** 6 | * Created by Denis on 18-Nov-16. 7 | */ 8 | data class InfoResponse( 9 | @JsonProperty("author") 10 | var author: String = "http://hixon.ru", 11 | 12 | @JsonProperty("info") 13 | var info: String = "Бот для создания голосований.", 14 | 15 | @JsonProperty("commands") 16 | var commands: List 17 | ) -------------------------------------------------------------------------------- /rest-voter/src/main/kotlin/ru/hixon/domain/VoteRequest.kt: -------------------------------------------------------------------------------- 1 | package ru.hixon.domain 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | 5 | 6 | /** 7 | * Created by Denis on 17-Nov-16. 8 | */ 9 | data class VoteRequest( 10 | @JsonProperty("text") 11 | var textCommand: String, 12 | 13 | @JsonProperty("username") 14 | var userName: String, 15 | 16 | @JsonProperty("display_name") 17 | var displayName: String 18 | ) -------------------------------------------------------------------------------- /rest-voter/src/main/kotlin/ru/hixon/domain/VoteResponse.kt: -------------------------------------------------------------------------------- 1 | package ru.hixon.domain 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty 4 | 5 | /** 6 | * Created by Denis on 17-Nov-16. 7 | */ 8 | data class VoteResponse( 9 | @JsonProperty("text") 10 | var text: String, 11 | 12 | @JsonProperty("bot") 13 | var botName: String = "rest-voter" 14 | ) -------------------------------------------------------------------------------- /rest-voter/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port = 8080 -------------------------------------------------------------------------------- /rt-repl-bot/.dockerignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | /.idea 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | *.iml 10 | /.lein-* 11 | /.nrepl-port 12 | -------------------------------------------------------------------------------- /rt-repl-bot/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /classes 3 | /checkouts 4 | /.idea 5 | pom.xml 6 | pom.xml.asc 7 | *.jar 8 | *.class 9 | *.iml 10 | /.lein-* 11 | /.nrepl-port 12 | -------------------------------------------------------------------------------- /rt-repl-bot/.java.policy: -------------------------------------------------------------------------------- 1 | grant { 2 | permission java.security.AllPermission; 3 | }; -------------------------------------------------------------------------------- /rt-repl-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM clojure 2 | RUN mkdir -p /usr/src/app 3 | WORKDIR /usr/src/app 4 | COPY project.clj /usr/src/app/ 5 | RUN lein deps 6 | COPY . /usr/src/app 7 | RUN mv "$(lein ring uberjar | sed -n 's/^Created \(.*standalone\.jar\)/\1/p')" app-standalone.jar 8 | CMD ["java", "-jar", "-Djava.security.policy=.java.policy", "app-standalone.jar"] 9 | -------------------------------------------------------------------------------- /rt-repl-bot/README.md: -------------------------------------------------------------------------------- 1 | # Clojure REPL bot for Radio-T 2 | 3 | To use this repl just prefix your clojure commands with `clj>` and it will be evaluated 4 | -------------------------------------------------------------------------------- /rt-repl-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "repl-bot" 2 | bot_display_name: "REPL-bot" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | - "Как дела?" 7 | - "Один два три" 8 | 9 | test_cases: 10 | - command: "clj> (+ 1 1)" 11 | result: "```\\n2" 12 | - command: "clj>" 13 | result: "```\\nEOF while reading" 14 | - command: "clj> (def var1 5)" 15 | result: "```\\n#'sandbox[0-9]{1,4}/var1" 16 | -------------------------------------------------------------------------------- /rt-repl-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | rt-repl-bot: 2 | build: . 3 | ports: 4 | - "8080:8080" -------------------------------------------------------------------------------- /rt-repl-bot/project.clj: -------------------------------------------------------------------------------- 1 | (defproject rt-repl-bot "1.0.0" 2 | :description "Clojure REPL bot for Radio-T chat" 3 | :min-lein-version "2.0.0" 4 | :dependencies [[org.clojure/clojure "1.8.0"] 5 | [org.clojure/tools.logging "0.3.1"] 6 | [ch.qos.logback/logback-classic "1.2.3"] 7 | [compojure "1.5.2"] 8 | [ring/ring-json "0.4.0"] 9 | [ring/ring-defaults "0.2.3"] 10 | [clojail "1.0.6"] 11 | [metrics-clojure "2.9.0"] 12 | [metrics-clojure-ring "2.9.0"]] 13 | :jvm-opts ["-Djava.security.policy=.java.policy"] 14 | :plugins [[lein-ring "0.11.0"]] 15 | :ring {:handler rt-repl-bot.handler/app :port 8080} 16 | :profiles 17 | {:dev {:dependencies [[javax.servlet/servlet-api "2.5"] 18 | [ring/ring-mock "0.3.0"]]}}) 19 | -------------------------------------------------------------------------------- /rt-repl-bot/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /rt-repl-bot/src/rt_repl_bot/repl.clj: -------------------------------------------------------------------------------- 1 | (ns rt-repl-bot.repl 2 | (:import (java.util.concurrent TimeoutException) 3 | (java.io StringWriter)) 4 | (:require [clojail.core :refer [sandbox]] 5 | [clojail.testers :refer [secure-tester-without-def]])) 6 | 7 | (def ^:private repl-sandbox 8 | "Clojure jailed sandbox instance" 9 | (sandbox 10 | secure-tester-without-def 11 | :timeout 5000 12 | :init '(require '[clojure.repl :refer [doc source]]) 13 | )) 14 | 15 | (defn eval-command [command] 16 | "Evaluates given command in jailed snadbox and returns the evaluated result couped with the output 17 | that was generated during the command execution" 18 | (with-open [out (StringWriter.)] 19 | (try 20 | (let [form (binding [*read-eval* false] (read-string command)) 21 | eval-result (repl-sandbox form {#'*out* out}) 22 | out-string (.toString out)] 23 | (if (.isEmpty out-string) 24 | (str eval-result) 25 | (str out-string "\n" eval-result))) 26 | (catch TimeoutException _ 27 | "Evaluation timed out in 5 seconds") 28 | (catch Exception e 29 | (.getMessage e))))) 30 | -------------------------------------------------------------------------------- /rt-repl-bot/test/rt_repl_bot/repl_test.clj: -------------------------------------------------------------------------------- 1 | (ns rt-repl-bot.repl-test 2 | (:require [clojure.test :refer :all] 3 | [rt-repl-bot.repl :refer :all])) 4 | 5 | (deftest repl-test 6 | 7 | (testing "Should evaluate valid forms" 8 | (is (= "2" (eval-command "(+ 1 1)"))) 9 | (is (re-matches #"#'sandbox[0-9]{1,4}/var1" (eval-command "(def var1 5)"))) 10 | (is (re-matches #"#'sandbox[0-9]{1,4}/fun1" (eval-command "(def fun1 #(+ %1 %2))"))) 11 | (is (re-matches #"#'sandbox[0-9]{1,4}/fun2" (eval-command "(defn fun2 [x y] (+ x y))"))) 12 | (is (= "10" (eval-command "(fun1 var1 5)")))) 13 | 14 | (testing "Should return evaluation error for invalid forms" 15 | (not (= "2" (eval-command "(+ 1 1"))) 16 | (not (= "text" (eval-command "text"))) 17 | (not (re-matches #"#'sandbox[0-9]{1,4}/.+" (eval-command "(def 5)"))) 18 | (not (re-matches #"#'sandbox[0-9]{1,4}/.+" (eval-command "(def fun1 [x y] (+ x y))"))) 19 | (not (re-matches #"#'sandbox[0-9]{1,4}/.+" (eval-command "(defn fun2 x y (+ x y))")))) 20 | 21 | (testing "Should fail on infinite loop scripts" 22 | (is (= "Evaluation timed out in 5 seconds" (eval-command "(while true)"))))) -------------------------------------------------------------------------------- /rtnumber-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | 3 | RUN set -x && \ 4 | apk add --no-cache ca-certificates && \ 5 | rm -rf /var/cache/apk/* /tmp/* 6 | 7 | COPY requirements.txt /tmp/ 8 | 9 | RUN pip install --no-cache-dir --disable-pip-version-check -r /tmp/requirements.txt 10 | 11 | COPY . /usr/rtnumber-bot 12 | 13 | WORKDIR /usr/rtnumber-bot 14 | 15 | EXPOSE 8080 16 | 17 | CMD ["python3", "-u", "main.py"] 18 | -------------------------------------------------------------------------------- /rtnumber-bot/README.md: -------------------------------------------------------------------------------- 1 | # rtnumber-bot 2 | 3 | Выводит номер подкаста и время до его начала 4 | 5 | ## Команды 6 | 7 | - выпуск! 8 | - номер! 9 | - время! 10 | -------------------------------------------------------------------------------- /rtnumber-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "rtnumber-bot" 2 | 3 | defaults: 4 | username: "rtnumber-bot" 5 | display_name: "rtnumber-bot" 6 | 7 | ignored_commands: 8 | - "Привет" 9 | - "время" 10 | - "Подскажите номер выпуска" 11 | 12 | test_cases: 13 | - command: "время!" 14 | result: ".+" 15 | -------------------------------------------------------------------------------- /rtnumber-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | rtnumber-bot: 2 | build: . 3 | container_name: rtnumber-bot 4 | hostname: rtnumber-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /rtnumber-bot/log_handler.py: -------------------------------------------------------------------------------- 1 | from logging import Handler 2 | 3 | 4 | class ArrayHandler(Handler): 5 | def __init__(self, max_count=20): 6 | self.records = [] 7 | self.max_count = max_count 8 | Handler.__init__(self) 9 | 10 | def emit(self, record): 11 | try: 12 | msg = self.format(record) 13 | self.records.append(msg) 14 | if len(self.records) > self.max_count: 15 | del(self.records[0]) 16 | except Exception: 17 | self.handleError(record) 18 | 19 | def logs(self): 20 | return self.records 21 | -------------------------------------------------------------------------------- /rtnumber-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==2.3.10 2 | requests==2.19.1 3 | pytz 4 | -------------------------------------------------------------------------------- /run_local.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Запускает проект локально на https://localhost 4 | 5 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | 7 | export SSL_KEY=nginx.key 8 | export SSL_CERT=nginx.crt 9 | 10 | ( 11 | cd "$DIR" 12 | SSL_KEYS_DIR="etc/ssl" 13 | 14 | if [ ! -f "$SSL_KEYS_DIR/$SSL_KEY" ] || [ ! -f "$SSL_KEYS_DIR/$SSL_CERT" ]; then 15 | openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ 16 | -subj "/C=US/ST=Test/L=Test/O=Dis/CN=localhost" \ 17 | -keyout "$SSL_KEYS_DIR/$SSL_KEY" \ 18 | -out "$SSL_KEYS_DIR/$SSL_CERT" 19 | fi 20 | 21 | docker-compose up 22 | ) 23 | -------------------------------------------------------------------------------- /sample-go/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | ADD . /go/src/github.com/umputun/rt-bot/sample-go 4 | RUN \ 5 | cd /go/src/github.com/umputun/rt-bot/sample-go && \ 6 | go get -v && \ 7 | go build -o /srv/sample-go && \ 8 | rm -rf /go/src/* 9 | 10 | EXPOSE 8080 11 | WORKDIR /srv 12 | CMD ["/srv/sample-go"] 13 | -------------------------------------------------------------------------------- /sample-go/README.md: -------------------------------------------------------------------------------- 1 | # Радио-Т пример бота 2 | https://github.com/umputun/rt-bot 3 | 4 | Этот бот не настоящий, просто для примера с целью помочь авторам, если у них вопросы по API. Он не будет активен в реальной жизни 5 | 6 | Бот слушает все сообщения и отвечает на любое ревeрсным текстом. 7 | -------------------------------------------------------------------------------- /sample-go/docker-compose.yml: -------------------------------------------------------------------------------- 1 | sample-go: 2 | build: . 3 | container_name: sample-go 4 | hostname: sample-go 5 | restart: always 6 | ports: 7 | - "8080:8080" 8 | -------------------------------------------------------------------------------- /search-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:alpine 2 | 3 | RUN apk add --no-cache ca-certificates 4 | 5 | ADD . /go/src/github.com/umputun/rt-bot/search-bot 6 | 7 | RUN \ 8 | cd /go/src/github.com/umputun/rt-bot/search-bot && \ 9 | go build -o /srv/search-bot && \ 10 | mkdir /srv/data && \ 11 | rm -rf /go/src/* 12 | 13 | EXPOSE 8080 14 | WORKDIR /srv 15 | CMD ["/srv/search-bot"] 16 | -------------------------------------------------------------------------------- /search-bot/Godeps/Readme: -------------------------------------------------------------------------------- 1 | This directory tree is generated automatically by godep. 2 | 3 | Please do not edit. 4 | 5 | See https://github.com/tools/godep for more information. 6 | -------------------------------------------------------------------------------- /search-bot/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Alexey Khalyapin 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. -------------------------------------------------------------------------------- /search-bot/README.md: -------------------------------------------------------------------------------- 1 | # Радио-Т поиск бот 2 | https://github.com/umputun/rt-bot 3 | 4 | ### Команды 5 | 6 | `Поиск` - помощь 7 | 8 | `Поиск [запрос[:число результатов]]` - поиск по выпускам 9 | 10 | `Выпуск [номер выпуска]` - содержание выпуска 11 | 12 | В запросе поддерживаются `-` и `+` префиксы и маска `*` 13 | 14 | Примеры: `Выпуск 520`, `Поиск docker swarm`, `Поиск +яндекс* +google :10` -------------------------------------------------------------------------------- /search-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "search-bot" 2 | 3 | ignored_commands: 4 | - "Привет!!!" 5 | 6 | test_cases: 7 | - command: "Поиск docker swarm" 8 | result: ".+" 9 | 10 | - command: "Поиск +яндекс* +google :10" 11 | result: ".+" 12 | -------------------------------------------------------------------------------- /search-bot/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | const ( 4 | Port = ":8080" 5 | DefaultSearchResults = 5 6 | MaxSearchResults = 30 7 | BotName = "search-bot" 8 | RadioTURL = "https://radio-t.com" 9 | RadioTArchiveURL = RadioTURL + "/archives/" 10 | ShowsFilePath = "./data/shows.gob" 11 | FetchWorkers = 10 12 | Author = "Alexey Khalyapin" 13 | Info = "Поиск по выпускам Радио-Т" 14 | Help = "В запросе поддерживаются `-` и `+` префиксы и маска `*`\\n" + 15 | "Примеры: `Выпуск 520`, `Поиск docker swarm`, `Поиск +яндекс* +google :10`" 16 | ) 17 | 18 | var ( 19 | Commans = []string{ 20 | "Поиск - помощь", 21 | "Поиск [запрос[:число результатов]] - поиск по выпускам", 22 | "Выпуск [номер выпуска] - содержание выпуска", 23 | } 24 | ) 25 | -------------------------------------------------------------------------------- /search-bot/data/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/search-bot/data/.keep -------------------------------------------------------------------------------- /search-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | search-bot: 2 | build: . 3 | container_name: search-bot 4 | hostname: search-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /search-bot/shows/fetch_test.go: -------------------------------------------------------------------------------- 1 | package shows 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | //func TestGetShows(t *testing.T) { 9 | // shows := GetShows(0, func(err error) { 10 | // fmt.Println(err) 11 | // }) 12 | // fmt.Println(shows) 13 | //} 14 | 15 | func TestFetchShowsLinks(t *testing.T) { 16 | links, err := fetchShowsLinks(0) 17 | if err != nil { 18 | t.Error(err) 19 | } 20 | for _, link := range links { 21 | fmt.Println(link) 22 | } 23 | 24 | } 25 | 26 | //func TestFetchShow(t *testing.T) { 27 | // show, err := fetchShow(radioTURL + "/p/2013/04/27/podcast-338/") 28 | // if err != nil { 29 | // t.Error(err) 30 | // } 31 | // fmt.Println(show) 32 | //} 33 | -------------------------------------------------------------------------------- /search-bot/shows/state.go: -------------------------------------------------------------------------------- 1 | package shows 2 | 3 | import ( 4 | "encoding/gob" 5 | "log" 6 | "os" 7 | 8 | "github.com/umputun/rt-bot/search-bot/config" 9 | ) 10 | 11 | func Load() *Shows { 12 | if _, err := os.Stat(config.ShowsFilePath); os.IsNotExist(err) { 13 | return NewShows() 14 | } 15 | 16 | f, err := os.Open(config.ShowsFilePath) 17 | if err != nil { 18 | log.Println("Open gob file error: " + err.Error()) 19 | return NewShows() 20 | } 21 | dec := gob.NewDecoder(f) 22 | var shows = NewShows() 23 | err = dec.Decode(shows) 24 | if err != nil { 25 | log.Println("Decode gob error: " + err.Error()) 26 | return NewShows() 27 | } 28 | return shows 29 | } 30 | 31 | func Save(shows *Shows) error { 32 | f, err := os.Create(config.ShowsFilePath) 33 | if err != nil { 34 | return err 35 | } 36 | enc := gob.NewEncoder(f) 37 | err = enc.Encode(shows) 38 | if err != nil { 39 | return err 40 | } 41 | return nil 42 | } 43 | -------------------------------------------------------------------------------- /search-bot/vendor/code.google.com/p/cascadia/.hgignore: -------------------------------------------------------------------------------- 1 | ^_ 2 | ^\. 3 | \.out$ 4 | \.6$ 5 | ~$ 6 | \.orig$ 7 | -------------------------------------------------------------------------------- /search-bot/vendor/code.google.com/p/cascadia/Makefile: -------------------------------------------------------------------------------- 1 | include $(GOROOT)/src/Make.inc 2 | 3 | TARG=cascadia 4 | 5 | GOFILES= \ 6 | parser.go \ 7 | selector.go \ 8 | 9 | include $(GOROOT)/src/Make.pkg 10 | 11 | format: 12 | gofmt -w ${GOFILES} *_test.go 13 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/PuerkitoBio/goquery/.gitignore: -------------------------------------------------------------------------------- 1 | *.sublime-* 2 | .DS_Store 3 | *.swp 4 | #*.*# 5 | tags 6 | goquery.test 7 | 8 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/PuerkitoBio/goquery/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.1 5 | - 1.2 6 | - 1.3 7 | - tip 8 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/alehano/batch/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | batch.iml -------------------------------------------------------------------------------- /search-bot/vendor/github.com/alehano/batch/README.md: -------------------------------------------------------------------------------- 1 | # batch 2 | Package batch runs multiple funcs asynchronously 3 | 4 | ```go 5 | 6 | workers := 5 7 | 8 | batch := New(workers, func(err error) { 9 | log.Println(err.Error()) 10 | }) 11 | 12 | batch.Start() 13 | 14 | for i := 1; i <= 10; i++ { 15 | 16 | // Here we pass i parameter from outer scope 17 | fn := func(i int) func() error { 18 | return func() error { 19 | // Here is our job 20 | err := SomeJob(i) 21 | if err != nil { 22 | return err 23 | } 24 | return nil 25 | } 26 | 27 | } 28 | batch.Add(fn(i)) 29 | } 30 | batch.Close() 31 | 32 | ``` -------------------------------------------------------------------------------- /search-bot/vendor/github.com/alehano/batch/batch.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package batch runs multiple funcs asynchronously 3 | You have to call Start() in the beginning and Close() in the end. 4 | */ 5 | package batch 6 | 7 | import "sync" 8 | 9 | type Batch struct { 10 | workers int 11 | jobChan chan func() error 12 | errFn func(error) 13 | wg *sync.WaitGroup 14 | } 15 | 16 | // New creates new Batch instance 17 | func New(workers int, errCallback func(error)) *Batch { 18 | return &Batch{ 19 | workers: workers, 20 | jobChan: make(chan func() error), 21 | errFn: errCallback, 22 | wg: new(sync.WaitGroup), 23 | } 24 | } 25 | 26 | func (b Batch) Start() { 27 | for i := 0; i < b.workers; i++ { 28 | go func() { 29 | for job := range b.jobChan { 30 | err := job() 31 | if err != nil { 32 | b.errFn(err) 33 | } 34 | b.wg.Done() 35 | } 36 | }() 37 | } 38 | } 39 | 40 | func (b Batch) Add(fn func() error) { 41 | b.wg.Add(1) 42 | b.jobChan <- fn 43 | } 44 | 45 | func (b Batch) Close() { 46 | b.wg.Wait() 47 | close(b.jobChan) 48 | } 49 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/.gitignore: -------------------------------------------------------------------------------- 1 | #* 2 | *.sublime-* 3 | *~ 4 | .#* 5 | .project 6 | .settings 7 | **/.idea/ 8 | **/*.iml 9 | .DS_Store 10 | query_string.y.go.tmp 11 | /analysis/token_filters/cld2/cld2-read-only 12 | /analysis/token_filters/cld2/libcld2_full.a 13 | /cmd/bleve/bleve 14 | vendor/** 15 | !vendor/manifest 16 | /y.output 17 | /search/query/y.output 18 | *.test 19 | tags 20 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: go 4 | 5 | go: 6 | - 1.6 7 | 8 | script: 9 | - go get golang.org/x/tools/cmd/cover 10 | - go get github.com/mattn/goveralls 11 | - go get github.com/kisielk/errcheck 12 | - go get -u github.com/FiloSottile/gvt 13 | - gvt restore 14 | - go test -v $(go list ./... | grep -v vendor/) 15 | - go vet $(go list ./... | grep -v vendor/) 16 | - errcheck $(go list ./... | grep -v vendor/) 17 | - docs/project-code-coverage.sh 18 | - docs/build_children.sh 19 | 20 | notifications: 21 | email: 22 | - marty.schoch@gmail.com 23 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Bleve 2 | 3 | We look forward to your contributions, but ask that you first review these guidelines. 4 | 5 | ### Sign the CLA 6 | 7 | As Bleve is a Couchbase project we require contributors accept the [Couchbase Contributor License Agreement](http://review.couchbase.org/static/individual_agreement.html). To sign this agreement log into the Couchbase [code review tool](http://review.couchbase.org/). The Bleve project does not use this code review tool but it is still used to track acceptance of the contributor license agreements. 8 | 9 | ### Submitting a Pull Request 10 | 11 | All types of contributions are welcome, but please keep the following in mind: 12 | 13 | - If you're planning a large change, you should really discuss it in a github issue or on the google group first. This helps avoid duplicate effort and spending time on something that may not be merged. 14 | - Existing tests should continue to pass, new tests for the contribution are nice to have. 15 | - All code should have gone through `go fmt` 16 | - All code should pass `go vet` 17 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/analysis/test_words.txt: -------------------------------------------------------------------------------- 1 | # full line comment 2 | marty 3 | steve # trailing comment 4 | | different format of comment 5 | dustin 6 | siri | different style trailing comment 7 | multiple words with different whitespace -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/config_app.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +build appengine appenginevm 16 | 17 | package bleve 18 | 19 | // in the appengine environment we cannot support disk based indexes 20 | // so we do no extra configuration in this method 21 | func initDisk() { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/config_disk.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // +build !appengine,!appenginevm 16 | 17 | package bleve 18 | 19 | import "github.com/blevesearch/bleve/index/store/boltdb" 20 | 21 | // in normal environments we configure boltdb as the default storage 22 | func initDisk() { 23 | // default kv store 24 | Config.DefaultKVStore = boltdb.Name 25 | } 26 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/index/store/boltdb/stats.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package boltdb 16 | 17 | import "encoding/json" 18 | 19 | type stats struct { 20 | s *Store 21 | } 22 | 23 | func (s *stats) MarshalJSON() ([]byte, error) { 24 | bs := s.s.db.Stats() 25 | return json.Marshal(bs) 26 | } 27 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/index/store/multiget.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2016 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package store 16 | 17 | // MultiGet is a helper function to retrieve mutiple keys from a 18 | // KVReader, and might be used by KVStore implementations that don't 19 | // have a native multi-get facility. 20 | func MultiGet(kvreader KVReader, keys [][]byte) ([][]byte, error) { 21 | vals := make([][]byte, 0, len(keys)) 22 | 23 | for i, key := range keys { 24 | val, err := kvreader.Get(key) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | vals[i] = val 30 | } 31 | 32 | return vals, nil 33 | } 34 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/index/upsidedown/benchmark_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BENCHMARKS=`grep "func Benchmark" *_test.go | sed 's/.*func //' | sed s/\(.*{//` 4 | 5 | for BENCHMARK in $BENCHMARKS 6 | do 7 | go test -v -run=xxx -bench=^$BENCHMARK$ -benchtime=10s -tags 'forestdb leveldb' | grep -v ok | grep -v PASS 8 | done 9 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/index/upsidedown/upsidedown.proto: -------------------------------------------------------------------------------- 1 | message BackIndexTermEntry { 2 | required string term = 1; 3 | required uint32 field = 2; 4 | } 5 | 6 | message BackIndexStoreEntry { 7 | required uint32 field = 1; 8 | repeated uint64 arrayPositions = 2; 9 | } 10 | 11 | message BackIndexRowValue { 12 | repeated BackIndexTermEntry termEntries = 1; 13 | repeated BackIndexStoreEntry storedEntries = 2; 14 | } 15 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/numeric/float.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package numeric 16 | 17 | import ( 18 | "math" 19 | ) 20 | 21 | func Float64ToInt64(f float64) int64 { 22 | fasint := int64(math.Float64bits(f)) 23 | if fasint < 0 { 24 | fasint = fasint ^ 0x7fffffffffffffff 25 | } 26 | return fasint 27 | } 28 | 29 | func Int64ToFloat64(i int64) float64 { 30 | if i < 0 { 31 | i ^= 0x7fffffffffffffff 32 | } 33 | return math.Float64frombits(uint64(i)) 34 | } 35 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/search/collector.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package search 16 | 17 | import ( 18 | "time" 19 | 20 | "github.com/blevesearch/bleve/index" 21 | 22 | "golang.org/x/net/context" 23 | ) 24 | 25 | type Collector interface { 26 | Collect(ctx context.Context, searcher Searcher, reader index.IndexReader) error 27 | Results() DocumentMatchCollection 28 | Total() uint64 29 | MaxScore() float64 30 | Took() time.Duration 31 | SetFacetsBuilder(facetsBuilder *FacetsBuilder) 32 | FacetResults() FacetResults 33 | } 34 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/search/explanation.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package search 16 | 17 | import ( 18 | "encoding/json" 19 | "fmt" 20 | ) 21 | 22 | type Explanation struct { 23 | Value float64 `json:"value"` 24 | Message string `json:"message"` 25 | Children []*Explanation `json:"children,omitempty"` 26 | } 27 | 28 | func (expl *Explanation) String() string { 29 | js, err := json.MarshalIndent(expl, "", " ") 30 | if err != nil { 31 | return fmt.Sprintf("error serializing explanation to json: %v", err) 32 | } 33 | return string(js) 34 | } 35 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/search/query/boost.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package query 16 | 17 | import "fmt" 18 | 19 | type Boost float64 20 | 21 | func (b *Boost) Value() float64 { 22 | if b == nil { 23 | return 1.0 24 | } 25 | return float64(*b) 26 | } 27 | 28 | func (b *Boost) GoString() string { 29 | if b == nil { 30 | return "boost unspecified" 31 | } 32 | return fmt.Sprintf("%f", *b) 33 | } 34 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/search/scorer/sqrt_cache.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package scorer 16 | 17 | import ( 18 | "math" 19 | ) 20 | 21 | var SqrtCache []float64 22 | 23 | const MaxSqrtCache = 64 24 | 25 | func init() { 26 | SqrtCache = make([]float64, MaxSqrtCache) 27 | for i := 0; i < MaxSqrtCache; i++ { 28 | SqrtCache[i] = math.Sqrt(float64(i)) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/bleve/search/searcher/ordered_searchers_list.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2014 Couchbase, Inc. 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 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package searcher 16 | 17 | import ( 18 | "github.com/blevesearch/bleve/search" 19 | ) 20 | 21 | type OrderedSearcherList []search.Searcher 22 | 23 | // sort.Interface 24 | 25 | func (otrl OrderedSearcherList) Len() int { 26 | return len(otrl) 27 | } 28 | 29 | func (otrl OrderedSearcherList) Less(i, j int) bool { 30 | return otrl[i].Count() < otrl[j].Count() 31 | } 32 | 33 | func (otrl OrderedSearcherList) Swap(i, j int) { 34 | otrl[i], otrl[j] = otrl[j], otrl[i] 35 | } 36 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/go-porterstemmer/.gitignore: -------------------------------------------------------------------------------- 1 | #* 2 | *.sublime-* 3 | *~ 4 | .#* 5 | .project 6 | .settings 7 | .DS_Store 8 | /testdata 9 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/go-porterstemmer/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.4 5 | 6 | script: 7 | - go get golang.org/x/tools/cmd/vet 8 | - go get golang.org/x/tools/cmd/cover 9 | - go get github.com/mattn/goveralls 10 | - go test -v -covermode=count -coverprofile=profile.out 11 | - go vet 12 | - goveralls -service drone.io -coverprofile=profile.out -repotoken $COVERALLS 13 | 14 | notifications: 15 | email: 16 | - marty.schoch@gmail.com 17 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/go-porterstemmer/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Charles Iliya Krempeaux :: http://changelog.ca/ 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 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/segment/.gitignore: -------------------------------------------------------------------------------- 1 | #* 2 | *.sublime-* 3 | *~ 4 | .#* 5 | .project 6 | .settings 7 | .DS_Store 8 | /maketesttables 9 | /workdir 10 | /segment-fuzz.zip -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/segment/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.7 5 | 6 | script: 7 | - go get golang.org/x/tools/cmd/cover 8 | - go get github.com/mattn/goveralls 9 | - go test -v -covermode=count -coverprofile=profile.out 10 | - go vet 11 | - goveralls -service drone.io -coverprofile=profile.out -repotoken $COVERALLS 12 | 13 | notifications: 14 | email: 15 | - marty.schoch@gmail.com 16 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/blevesearch/segment/segment_fuzz.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 Couchbase, Inc. 2 | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 3 | // except in compliance with the License. You may obtain a copy of the License at 4 | // http://www.apache.org/licenses/LICENSE-2.0 5 | // Unless required by applicable law or agreed to in writing, software distributed under the 6 | // License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 7 | // either express or implied. See the License for the specific language governing permissions 8 | // and limitations under the License. 9 | 10 | // +build gofuzz 11 | 12 | package segment 13 | 14 | func Fuzz(data []byte) int { 15 | 16 | vals := make([][]byte, 0, 10000) 17 | types := make([]int, 0, 10000) 18 | if _, _, _, err := SegmentWordsDirect(data, vals, types); err != nil { 19 | return 0 20 | } 21 | return 1 22 | } 23 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/.gitignore: -------------------------------------------------------------------------------- 1 | *.prof 2 | *.test 3 | *.swp 4 | /bin/ 5 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Ben Johnson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/Makefile: -------------------------------------------------------------------------------- 1 | BRANCH=`git rev-parse --abbrev-ref HEAD` 2 | COMMIT=`git rev-parse --short HEAD` 3 | GOLDFLAGS="-X main.branch $(BRANCH) -X main.commit $(COMMIT)" 4 | 5 | default: build 6 | 7 | race: 8 | @go test -v -race -test.run="TestSimulate_(100op|1000op)" 9 | 10 | # go get github.com/kisielk/errcheck 11 | errcheck: 12 | @errcheck -ignorepkg=bytes -ignore=os:Remove github.com/boltdb/bolt 13 | 14 | test: 15 | @go test -v -cover . 16 | @go test -v ./cmd/bolt 17 | 18 | .PHONY: fmt test 19 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/appveyor.yml: -------------------------------------------------------------------------------- 1 | version: "{build}" 2 | 3 | os: Windows Server 2012 R2 4 | 5 | clone_folder: c:\gopath\src\github.com\boltdb\bolt 6 | 7 | environment: 8 | GOPATH: c:\gopath 9 | 10 | install: 11 | - echo %PATH% 12 | - echo %GOPATH% 13 | - go version 14 | - go env 15 | - go get -v -t ./... 16 | 17 | build_script: 18 | - go test -v ./... 19 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_386.go: -------------------------------------------------------------------------------- 1 | package bolt 2 | 3 | // maxMapSize represents the largest mmap size supported by Bolt. 4 | const maxMapSize = 0x7FFFFFFF // 2GB 5 | 6 | // maxAllocSize is the size used when creating array pointers. 7 | const maxAllocSize = 0xFFFFFFF 8 | 9 | // Are unaligned load/stores broken on this arch? 10 | var brokenUnaligned = false 11 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_amd64.go: -------------------------------------------------------------------------------- 1 | package bolt 2 | 3 | // maxMapSize represents the largest mmap size supported by Bolt. 4 | const maxMapSize = 0xFFFFFFFFFFFF // 256TB 5 | 6 | // maxAllocSize is the size used when creating array pointers. 7 | const maxAllocSize = 0x7FFFFFFF 8 | 9 | // Are unaligned load/stores broken on this arch? 10 | var brokenUnaligned = false 11 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_arm.go: -------------------------------------------------------------------------------- 1 | package bolt 2 | 3 | import "unsafe" 4 | 5 | // maxMapSize represents the largest mmap size supported by Bolt. 6 | const maxMapSize = 0x7FFFFFFF // 2GB 7 | 8 | // maxAllocSize is the size used when creating array pointers. 9 | const maxAllocSize = 0xFFFFFFF 10 | 11 | // Are unaligned load/stores broken on this arch? 12 | var brokenUnaligned bool 13 | 14 | func init() { 15 | // Simple check to see whether this arch handles unaligned load/stores 16 | // correctly. 17 | 18 | // ARM9 and older devices require load/stores to be from/to aligned 19 | // addresses. If not, the lower 2 bits are cleared and that address is 20 | // read in a jumbled up order. 21 | 22 | // See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15414.html 23 | 24 | raw := [6]byte{0xfe, 0xef, 0x11, 0x22, 0x22, 0x11} 25 | val := *(*uint32)(unsafe.Pointer(uintptr(unsafe.Pointer(&raw)) + 2)) 26 | 27 | brokenUnaligned = val != 0x11222211 28 | } 29 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_arm64.go: -------------------------------------------------------------------------------- 1 | // +build arm64 2 | 3 | package bolt 4 | 5 | // maxMapSize represents the largest mmap size supported by Bolt. 6 | const maxMapSize = 0xFFFFFFFFFFFF // 256TB 7 | 8 | // maxAllocSize is the size used when creating array pointers. 9 | const maxAllocSize = 0x7FFFFFFF 10 | 11 | // Are unaligned load/stores broken on this arch? 12 | var brokenUnaligned = false 13 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_linux.go: -------------------------------------------------------------------------------- 1 | package bolt 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | // fdatasync flushes written data to a file descriptor. 8 | func fdatasync(db *DB) error { 9 | return syscall.Fdatasync(int(db.file.Fd())) 10 | } 11 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_openbsd.go: -------------------------------------------------------------------------------- 1 | package bolt 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | const ( 9 | msAsync = 1 << iota // perform asynchronous writes 10 | msSync // perform synchronous writes 11 | msInvalidate // invalidate cached data 12 | ) 13 | 14 | func msync(db *DB) error { 15 | _, _, errno := syscall.Syscall(syscall.SYS_MSYNC, uintptr(unsafe.Pointer(db.data)), uintptr(db.datasz), msInvalidate) 16 | if errno != 0 { 17 | return errno 18 | } 19 | return nil 20 | } 21 | 22 | func fdatasync(db *DB) error { 23 | if db.data != nil { 24 | return msync(db) 25 | } 26 | return db.file.Sync() 27 | } 28 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_ppc.go: -------------------------------------------------------------------------------- 1 | // +build ppc 2 | 3 | package bolt 4 | 5 | // maxMapSize represents the largest mmap size supported by Bolt. 6 | const maxMapSize = 0x7FFFFFFF // 2GB 7 | 8 | // maxAllocSize is the size used when creating array pointers. 9 | const maxAllocSize = 0xFFFFFFF 10 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_ppc64.go: -------------------------------------------------------------------------------- 1 | // +build ppc64 2 | 3 | package bolt 4 | 5 | // maxMapSize represents the largest mmap size supported by Bolt. 6 | const maxMapSize = 0xFFFFFFFFFFFF // 256TB 7 | 8 | // maxAllocSize is the size used when creating array pointers. 9 | const maxAllocSize = 0x7FFFFFFF 10 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_ppc64le.go: -------------------------------------------------------------------------------- 1 | // +build ppc64le 2 | 3 | package bolt 4 | 5 | // maxMapSize represents the largest mmap size supported by Bolt. 6 | const maxMapSize = 0xFFFFFFFFFFFF // 256TB 7 | 8 | // maxAllocSize is the size used when creating array pointers. 9 | const maxAllocSize = 0x7FFFFFFF 10 | 11 | // Are unaligned load/stores broken on this arch? 12 | var brokenUnaligned = false 13 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/bolt_s390x.go: -------------------------------------------------------------------------------- 1 | // +build s390x 2 | 3 | package bolt 4 | 5 | // maxMapSize represents the largest mmap size supported by Bolt. 6 | const maxMapSize = 0xFFFFFFFFFFFF // 256TB 7 | 8 | // maxAllocSize is the size used when creating array pointers. 9 | const maxAllocSize = 0x7FFFFFFF 10 | 11 | // Are unaligned load/stores broken on this arch? 12 | var brokenUnaligned = false 13 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/boltdb/bolt/boltsync_unix.go: -------------------------------------------------------------------------------- 1 | // +build !windows,!plan9,!linux,!openbsd 2 | 3 | package bolt 4 | 5 | // fdatasync flushes written data to a file descriptor. 6 | func fdatasync(db *DB) error { 7 | return db.file.Sync() 8 | } 9 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/steveyen/gtreap/.gitignore: -------------------------------------------------------------------------------- 1 | #* 2 | *~ 3 | *.test 4 | tmp 5 | 6 | -------------------------------------------------------------------------------- /search-bot/vendor/github.com/steveyen/gtreap/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 Steve Yen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/.gitignore: -------------------------------------------------------------------------------- 1 | _obj/ 2 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm.s: -------------------------------------------------------------------------------- 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 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | TEXT ·use(SB),NOSPLIT,$0 10 | RET 11 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_darwin_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, Darwin 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, Darwin 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_darwin_arm.s: -------------------------------------------------------------------------------- 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 | // +build !gccgo 6 | // +build arm,darwin 7 | 8 | #include "textflag.h" 9 | 10 | // 11 | // System call support for ARM, Darwin 12 | // 13 | 14 | // Just jump to package syscall's implementation for all these functions. 15 | // The runtime may know about them. 16 | 17 | TEXT ·Syscall(SB),NOSPLIT,$0-28 18 | B syscall·Syscall(SB) 19 | 20 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 21 | B syscall·Syscall6(SB) 22 | 23 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 24 | B syscall·Syscall9(SB) 25 | 26 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 27 | B syscall·RawSyscall(SB) 28 | 29 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 30 | B syscall·RawSyscall6(SB) 31 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s: -------------------------------------------------------------------------------- 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 | // +build !gccgo 6 | // +build arm64,darwin 7 | 8 | #include "textflag.h" 9 | 10 | // 11 | // System call support for AMD64, Darwin 12 | // 13 | 14 | // Just jump to package syscall's implementation for all these functions. 15 | // The runtime may know about them. 16 | 17 | TEXT ·Syscall(SB),NOSPLIT,$0-56 18 | B syscall·Syscall(SB) 19 | 20 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 21 | B syscall·Syscall6(SB) 22 | 23 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 24 | B syscall·Syscall9(SB) 25 | 26 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 27 | B syscall·RawSyscall(SB) 28 | 29 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 30 | B syscall·RawSyscall6(SB) 31 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_dragonfly_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, FreeBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-32 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-44 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-56 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-32 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-44 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, DragonFly 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-64 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-88 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-112 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-64 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-88 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_freebsd_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, FreeBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, FreeBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for ARM, FreeBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | B syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | B syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | B syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | B syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | B syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_linux_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for 386, Linux 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 23 | JMP syscall·RawSyscall(SB) 24 | 25 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 26 | JMP syscall·RawSyscall6(SB) 27 | 28 | TEXT ·socketcall(SB),NOSPLIT,$0-36 29 | JMP syscall·socketcall(SB) 30 | 31 | TEXT ·rawsocketcall(SB),NOSPLIT,$0-36 32 | JMP syscall·rawsocketcall(SB) 33 | 34 | TEXT ·seek(SB),NOSPLIT,$0-28 35 | JMP syscall·seek(SB) 36 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_linux_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for AMD64, Linux 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 23 | JMP syscall·RawSyscall(SB) 24 | 25 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 26 | JMP syscall·RawSyscall6(SB) 27 | 28 | TEXT ·gettimeofday(SB),NOSPLIT,$0-16 29 | JMP syscall·gettimeofday(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_linux_arm.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for arm, Linux 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | B syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | B syscall·Syscall6(SB) 21 | 22 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 23 | B syscall·RawSyscall(SB) 24 | 25 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 26 | B syscall·RawSyscall6(SB) 27 | 28 | TEXT ·seek(SB),NOSPLIT,$0-32 29 | B syscall·seek(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_linux_arm64.s: -------------------------------------------------------------------------------- 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 | // +build linux 6 | // +build arm64 7 | // +build !gccgo 8 | 9 | #include "textflag.h" 10 | 11 | // Just jump to package syscall's implementation for all these functions. 12 | // The runtime may know about them. 13 | 14 | TEXT ·Syscall(SB),NOSPLIT,$0-56 15 | B syscall·Syscall(SB) 16 | 17 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 18 | B syscall·Syscall6(SB) 19 | 20 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 21 | B syscall·RawSyscall(SB) 22 | 23 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 24 | B syscall·RawSyscall6(SB) 25 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_linux_ppc64x.s: -------------------------------------------------------------------------------- 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 | // +build linux 6 | // +build ppc64 ppc64le 7 | // +build !gccgo 8 | 9 | #include "textflag.h" 10 | 11 | // 12 | // System calls for ppc64, Linux 13 | // 14 | 15 | // Just jump to package syscall's implementation for all these functions. 16 | // The runtime may know about them. 17 | 18 | TEXT ·Syscall(SB),NOSPLIT,$0-56 19 | BR syscall·Syscall(SB) 20 | 21 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 22 | BR syscall·Syscall6(SB) 23 | 24 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 25 | BR syscall·RawSyscall(SB) 26 | 27 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 28 | BR syscall·RawSyscall6(SB) 29 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_netbsd_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, NetBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, NetBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s: -------------------------------------------------------------------------------- 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for ARM, NetBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | B syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | B syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | B syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | B syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | B syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_openbsd_386.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for 386, OpenBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-28 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-40 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-52 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-28 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System call support for AMD64, OpenBSD 11 | // 12 | 13 | // Just jump to package syscall's implementation for all these functions. 14 | // The runtime may know about them. 15 | 16 | TEXT ·Syscall(SB),NOSPLIT,$0-56 17 | JMP syscall·Syscall(SB) 18 | 19 | TEXT ·Syscall6(SB),NOSPLIT,$0-80 20 | JMP syscall·Syscall6(SB) 21 | 22 | TEXT ·Syscall9(SB),NOSPLIT,$0-104 23 | JMP syscall·Syscall9(SB) 24 | 25 | TEXT ·RawSyscall(SB),NOSPLIT,$0-56 26 | JMP syscall·RawSyscall(SB) 27 | 28 | TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 29 | JMP syscall·RawSyscall6(SB) 30 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/asm_solaris_amd64.s: -------------------------------------------------------------------------------- 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 | // +build !gccgo 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for amd64, Solaris are implemented in runtime/syscall_solaris.go 11 | // 12 | 13 | TEXT ·sysvicall6(SB),NOSPLIT,$0-64 14 | JMP syscall·sysvicall6(SB) 15 | 16 | TEXT ·rawSysvicall6(SB),NOSPLIT,$0-64 17 | JMP syscall·rawSysvicall6(SB) 18 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/constants.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 | // +build darwin dragonfly freebsd linux netbsd openbsd solaris 6 | 7 | package unix 8 | 9 | const ( 10 | R_OK = 0x4 11 | W_OK = 0x2 12 | X_OK = 0x1 13 | ) 14 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/env_unix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 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 dragonfly freebsd linux netbsd openbsd solaris 6 | 7 | // Unix environment variables. 8 | 9 | package unix 10 | 11 | import "syscall" 12 | 13 | func Getenv(key string) (value string, found bool) { 14 | return syscall.Getenv(key) 15 | } 16 | 17 | func Setenv(key, value string) error { 18 | return syscall.Setenv(key, value) 19 | } 20 | 21 | func Clearenv() { 22 | syscall.Clearenv() 23 | } 24 | 25 | func Environ() []string { 26 | return syscall.Environ() 27 | } 28 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/env_unset.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 | // +build go1.4 6 | 7 | package unix 8 | 9 | import "syscall" 10 | 11 | func Unsetenv(key string) error { 12 | // This was added in Go 1.4. 13 | return syscall.Unsetenv(key) 14 | } 15 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/flock.go: -------------------------------------------------------------------------------- 1 | // +build linux darwin freebsd openbsd netbsd dragonfly 2 | 3 | // Copyright 2014 The Go Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style 5 | // license that can be found in the LICENSE file. 6 | 7 | // +build darwin dragonfly freebsd linux netbsd openbsd 8 | 9 | package unix 10 | 11 | import "unsafe" 12 | 13 | // fcntl64Syscall is usually SYS_FCNTL, but is overridden on 32-bit Linux 14 | // systems by flock_linux_32bit.go to be SYS_FCNTL64. 15 | var fcntl64Syscall uintptr = SYS_FCNTL 16 | 17 | // FcntlFlock performs a fcntl syscall for the F_GETLK, F_SETLK or F_SETLKW command. 18 | func FcntlFlock(fd uintptr, cmd int, lk *Flock_t) error { 19 | _, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(unsafe.Pointer(lk))) 20 | if errno == 0 { 21 | return nil 22 | } 23 | return errno 24 | } 25 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/flock_linux_32bit.go: -------------------------------------------------------------------------------- 1 | // +build linux,386 linux,arm 2 | 3 | // Copyright 2014 The Go Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style 5 | // license that can be found in the LICENSE file. 6 | 7 | package unix 8 | 9 | func init() { 10 | // On 32-bit Linux systems, the fcntl syscall that matches Go's 11 | // Flock_t type is SYS_FCNTL64, not SYS_FCNTL. 12 | fcntl64Syscall = SYS_FCNTL64 13 | } 14 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/gccgo_c.c: -------------------------------------------------------------------------------- 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 | // +build gccgo 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define _STRINGIFY2_(x) #x 12 | #define _STRINGIFY_(x) _STRINGIFY2_(x) 13 | #define GOSYM_PREFIX _STRINGIFY_(__USER_LABEL_PREFIX__) 14 | 15 | // Call syscall from C code because the gccgo support for calling from 16 | // Go to C does not support varargs functions. 17 | 18 | struct ret { 19 | uintptr_t r; 20 | uintptr_t err; 21 | }; 22 | 23 | struct ret 24 | gccgoRealSyscall(uintptr_t trap, uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9) 25 | { 26 | struct ret r; 27 | 28 | errno = 0; 29 | r.r = syscall(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9); 30 | r.err = errno; 31 | return r; 32 | } 33 | 34 | // Define the use function in C so that it is not inlined. 35 | 36 | extern void use(void *) __asm__ (GOSYM_PREFIX GOPKGPATH ".use") __attribute__((noinline)); 37 | 38 | void 39 | use(void *p __attribute__ ((unused))) 40 | { 41 | } 42 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/gccgo_linux_amd64.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 | // +build gccgo,linux,amd64 6 | 7 | package unix 8 | 9 | import "syscall" 10 | 11 | //extern gettimeofday 12 | func realGettimeofday(*Timeval, *byte) int32 13 | 14 | func gettimeofday(tv *Timeval) (err syscall.Errno) { 15 | r := realGettimeofday(tv, nil) 16 | if r < 0 { 17 | return syscall.GetErrno() 18 | } 19 | return 0 20 | } 21 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/mksysnum_darwin.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | # Copyright 2009 The Go Authors. All rights reserved. 3 | # Use of this source code is governed by a BSD-style 4 | # license that can be found in the LICENSE file. 5 | # 6 | # Generate system call table for Darwin from sys/syscall.h 7 | 8 | use strict; 9 | 10 | if($ENV{'GOARCH'} eq "" || $ENV{'GOOS'} eq "") { 11 | print STDERR "GOARCH or GOOS not defined in environment\n"; 12 | exit 1; 13 | } 14 | 15 | my $command = "mksysnum_darwin.pl " . join(' ', @ARGV); 16 | 17 | print <){ 29 | if(/^#define\s+SYS_(\w+)\s+([0-9]+)/){ 30 | my $name = $1; 31 | my $num = $2; 32 | $name =~ y/a-z/A-Z/; 33 | print " SYS_$name = $num;" 34 | } 35 | } 36 | 37 | print <= 10 { 20 | buf[i] = byte(val%10 + '0') 21 | i-- 22 | val /= 10 23 | } 24 | buf[i] = byte(val + '0') 25 | return string(buf[i:]) 26 | } 27 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/syscall_no_getwd.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 dragonfly freebsd netbsd openbsd 6 | 7 | package unix 8 | 9 | const ImplementsGetwd = false 10 | 11 | func Getwd() (string, error) { return "", ENOTSUP } 12 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/syscall_solaris_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 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 amd64,solaris 6 | 7 | package unix 8 | 9 | func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) } 10 | 11 | func NsecToTimespec(nsec int64) (ts Timespec) { 12 | ts.Sec = nsec / 1e9 13 | ts.Nsec = nsec % 1e9 14 | return 15 | } 16 | 17 | func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 } 18 | 19 | func NsecToTimeval(nsec int64) (tv Timeval) { 20 | nsec += 999 // round up to microsecond 21 | tv.Usec = nsec % 1e9 / 1e3 22 | tv.Sec = int64(nsec / 1e9) 23 | return 24 | } 25 | 26 | func (iov *Iovec) SetLen(length int) { 27 | iov.Len = uint64(length) 28 | } 29 | 30 | func (cmsg *Cmsghdr) SetLen(length int) { 31 | cmsg.Len = uint32(length) 32 | } 33 | 34 | func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) { 35 | // TODO(aram): implement this, see issue 5847. 36 | panic("unimplemented") 37 | } 38 | -------------------------------------------------------------------------------- /search-bot/vendor/golang.org/x/sys/unix/zsysnum_solaris_amd64.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 | // +build amd64,solaris 6 | 7 | package unix 8 | 9 | // TODO(aram): remove these before Go 1.3. 10 | const ( 11 | SYS_EXECVE = 59 12 | SYS_FCNTL = 62 13 | ) 14 | -------------------------------------------------------------------------------- /search-bot/vendor/gopkg.in/robfig/cron.v2/.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 | -------------------------------------------------------------------------------- /search-bot/vendor/gopkg.in/robfig/cron.v2/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | -------------------------------------------------------------------------------- /search-bot/vendor/gopkg.in/robfig/cron.v2/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 Rob Figueiredo 2 | All Rights Reserved. 3 | 4 | MIT LICENSE 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | 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, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /search-bot/vendor/gopkg.in/robfig/cron.v2/README.md: -------------------------------------------------------------------------------- 1 | [![GoDoc](http://godoc.org/github.com/robfig/cron?status.png)](http://godoc.org/github.com/robfig/cron) 2 | -------------------------------------------------------------------------------- /search-bot/vendor/gopkg.in/robfig/cron.v2/constantdelay.go: -------------------------------------------------------------------------------- 1 | package cron 2 | 3 | import "time" 4 | 5 | // ConstantDelaySchedule represents a simple recurring duty cycle, e.g. "Every 5 minutes". 6 | // It does not support jobs more frequent than once a second. 7 | type ConstantDelaySchedule struct { 8 | Delay time.Duration 9 | } 10 | 11 | // Every returns a crontab Schedule that activates once every duration. 12 | // Delays of less than a second are not supported (will round up to 1 second). 13 | // Any fields less than a Second are truncated. 14 | func Every(duration time.Duration) ConstantDelaySchedule { 15 | if duration < time.Second { 16 | duration = time.Second 17 | } 18 | return ConstantDelaySchedule{ 19 | Delay: duration - time.Duration(duration.Nanoseconds())%time.Second, 20 | } 21 | } 22 | 23 | // Next returns the next time this should be run. 24 | // This rounds so that the next activation time will be on the second. 25 | func (schedule ConstantDelaySchedule) Next(t time.Time) time.Time { 26 | return t.Add(schedule.Delay - time.Duration(t.Nanosecond())*time.Nanosecond) 27 | } 28 | -------------------------------------------------------------------------------- /sovet-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:argon 2 | 3 | # Create app directory 4 | RUN mkdir -p /usr/src/app 5 | WORKDIR /usr/src/app 6 | 7 | # Install app dependencies 8 | COPY package.json /usr/src/app/ 9 | RUN npm install --silent 10 | 11 | # Bundle app source 12 | COPY . /usr/src/app 13 | 14 | EXPOSE 8080 15 | CMD ["npm", "start"] 16 | -------------------------------------------------------------------------------- /sovet-bot/README.md: -------------------------------------------------------------------------------- 1 | Бот советчик, реагирует на регулярку `/совет|грей|грэй|gray|как\sжить|подскажите|\?/` и подтягивает совет из `http://fucking-great-advice.ru/` -------------------------------------------------------------------------------- /sovet-bot/_bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "sovet-bot" 2 | bot_display_name: "советчик" 3 | 4 | ignored_commands: 5 | - "Привет" 6 | 7 | test_cases: 8 | - command: "совет" 9 | result: ".+" 10 | 11 | - command: "как жить?" 12 | result: ".+" 13 | -------------------------------------------------------------------------------- /sovet-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | sovet-bot: 2 | build: . 3 | container_name: sovet-bot 4 | hostname: sovet-bot 5 | restart: sovet-bot 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /sovet-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sovet-bot", 3 | "version": "1.0.0", 4 | "description": "bot for radio-t", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "node app.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "body-parser": "^1.15.2", 14 | "express": "^4.14.0", 15 | "request": "^2.78.0", 16 | "request-promise": "^4.1.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /stat-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM perl:5 2 | 3 | ADD http://download.cdn.yandex.net/mystem/mystem-2.1-linux3.2-64bit.tar.gz /tmp/mystem.tar.gz 4 | 5 | RUN cpanm Mojolicious JSON 6 | 7 | COPY . /stat-bot 8 | WORKDIR /stat-bot 9 | 10 | RUN set -x && \ 11 | tar -xvf /tmp/mystem.tar.gz && \ 12 | chmod +x mystem && \ 13 | rm -rf /tmp/* 14 | 15 | EXPOSE 8080 16 | 17 | CMD ["perl", "stat-bot.pl"] 18 | -------------------------------------------------------------------------------- /stat-bot/README.md: -------------------------------------------------------------------------------- 1 | # Простой stat-bot 2 | 3 | Ботик для чатика Радио-Т выполняющий две простые функции: 4 | 5 | - Ведет статистику болтунов в чате 6 | - Подсчитывает количество употреблений слов выдает их в разных срезах 7 | 8 | ## Что можно спросить: 9 | 10 | - `Кто болтун?` - для того чтобы узнать самого болтливого в чате за период накопления статистики (бот пока теряет ее при перезапуске) или `Кто сегодня болтун?` чтобы узнать саомго болтливого за сегодня (по UTC, что как раз нормально накладывается на эфир) 11 | - `Топ болтунов` - 5 самых болтливых юзеров. Ну или `Топ болтунов сегодня` - топ за сегодня. 12 | - `О чем говорили?` - пять самых популярных слов-существительных. По идее это должно характеризовать содержание беседы )) 13 | - `Как в целом?` - эмоциональная окраска беседы из пяти самых популярных прилагательных 14 | - Ну и `А что делать?` - подборка из пяти самых популярных глаголов в чате за сегодня 15 | - Можно спросить `Сколько раз употребили слово бобук?` чтобы узнать ответ на этот и подобный вопросы. К сожалению, шутка с docker'ом не прокатит, потому что бот пока не учитывает некириллические написания 16 | - Ну и можно познакомиться написав `Давайте познакомимся!` -------------------------------------------------------------------------------- /stat-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "stat-bot" 2 | 3 | ignored_commands: 4 | - "Привет" 5 | 6 | test_cases: 7 | - command: "Кто болтун?" 8 | result: ".+" 9 | 10 | - command: "Кто сегодня болтун?" 11 | result: ".+" 12 | 13 | - command: "О чем говорили?" 14 | result: ".+" 15 | -------------------------------------------------------------------------------- /stat-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | stat-bot: 2 | build: . 3 | ports: 4 | - "8080:8080" -------------------------------------------------------------------------------- /timezone-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine 2 | ENV FLASK_APP=timezone_bot.py \ 3 | APP_CONFIG=config/common.cfg \ 4 | GOOGLE_KEY=AIzaSyATWIZ_mnGgKVk0It9JteGR4WJr0lxGi4A 5 | RUN apk add --no-cache python3 python3-dev build-base linux-headers 6 | WORKDIR /home/app 7 | RUN pip3 install --upgrade pip 8 | RUN pip3 install certifi==2015.04.28 9 | COPY requirements requirements 10 | RUN pip3 install -r requirements/production.txt 11 | COPY . . 12 | 13 | CMD uwsgi --http :8080 --manage-script-name --mount /home/app=timezone_bot:app 14 | -------------------------------------------------------------------------------- /timezone-bot/README.rst: -------------------------------------------------------------------------------- 1 | Timezone-bot 2 | ############ 3 | 4 | Бот реагирует на команду ``время в/во `` 5 | 6 | Примеры: ``время в красноярске``, ``время во владивостоке`` 7 | 8 | -------------------------------------------------------------------------------- /timezone-bot/_bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "timezone-bot" 2 | 3 | ignored_commands: 4 | - "Привет" 5 | 6 | test_cases: 7 | - command: "время в красноярске" 8 | result: ".+" 9 | 10 | - command: "время во владивостоке" 11 | result: ".+" 12 | -------------------------------------------------------------------------------- /timezone-bot/config/common.cfg: -------------------------------------------------------------------------------- 1 | BOT_NAME = 'timezone-bot' 2 | TIME_FORMAT = '%d.%m.%Y %H:%M:%S' -------------------------------------------------------------------------------- /timezone-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | timezone-bot: 2 | build: . 3 | container_name: timezone-bot 4 | hostname: timezone-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /timezone-bot/requirements/common.in: -------------------------------------------------------------------------------- 1 | flask 2 | googlemaps 3 | pytz -------------------------------------------------------------------------------- /timezone-bot/requirements/local.in: -------------------------------------------------------------------------------- 1 | ipython 2 | coverage -------------------------------------------------------------------------------- /timezone-bot/requirements/production.in: -------------------------------------------------------------------------------- 1 | uwsgi -------------------------------------------------------------------------------- /timezone-bot/requirements/production.txt: -------------------------------------------------------------------------------- 1 | # 2 | # This file is autogenerated by pip-compile 3 | # To update, run: 4 | # 5 | # pip-compile --output-file requirements/production.txt requirements/common.in requirements/production.in 6 | # 7 | click==6.6 # via flask 8 | flask==0.11.1 9 | googlemaps==2.4.4 10 | itsdangerous==0.24 # via flask 11 | Jinja2==2.8 # via flask 12 | MarkupSafe==0.23 # via jinja2 13 | pytz==2016.7 14 | pyyaml==3.12 15 | requests==2.10.0 # via googlemaps 16 | uwsgi==2.0.14 17 | Werkzeug==0.11.11 # via flask 18 | -------------------------------------------------------------------------------- /timezone-bot/tasks.py: -------------------------------------------------------------------------------- 1 | from invoke import task 2 | 3 | 4 | @task 5 | def lock(ctx, env='local', upgrade=False): 6 | """Lock dependencies 7 | 8 | Lock *.in files to populate *.txt file with frozen versions 9 | """ 10 | upgrade_str = '' 11 | 12 | if upgrade: 13 | upgrade_str = '-U' 14 | 15 | ctx.run( 16 | 'pip-compile {upgrade_str} requirements/common.in ' 17 | 'requirements/{env}.in --output-file requirements/{env}.txt'.format( 18 | env=env, upgrade_str=upgrade_str 19 | ) 20 | ) 21 | 22 | 23 | @task 24 | def install(ctx, env='local'): 25 | """Install dependencies 26 | 27 | Install dependencies from *.txt file 28 | """ 29 | 30 | ctx.run('pip install -r requirements/{env}.txt'.format(env=env)) 31 | -------------------------------------------------------------------------------- /tweet-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.5-alpine 2 | 3 | RUN set -x && \ 4 | apk add --no-cache --virtual builddeps ca-certificates && \ 5 | rm -rf /var/cache/apk/* /tmp/* 6 | 7 | COPY requirements.txt /tmp/ 8 | 9 | RUN pip3 install --no-cache-dir --disable-pip-version-check -r /tmp/requirements.txt 10 | 11 | RUN mkdir /usr/tweet-bot/ 12 | 13 | COPY . /usr/tweet-bot/ 14 | 15 | WORKDIR /usr/tweet-bot/ 16 | 17 | EXPOSE 8080 18 | 19 | CMD ["python3", "-u", "main.py"] 20 | -------------------------------------------------------------------------------- /tweet-bot/README.md: -------------------------------------------------------------------------------- 1 | # tweet-bot 2 | 3 | Выводит последний твит из указанного твиттер-аккаунта. 4 | 5 | ## Команды 6 | 7 | - !tweet username 8 | - !твит username 9 | - !bobuk 10 | - bobuk! 11 | - !umputun 12 | - umputun! 13 | -------------------------------------------------------------------------------- /tweet-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "tweet-bot" 2 | 3 | defaults: 4 | username: "tweet-bot" 5 | display_name: "tweet-bot" 6 | 7 | ignored_commands: 8 | - "!tweet" 9 | - "!твит ksenks!" 10 | - "!твит qqqqqqqqqqqqqqqq" 11 | 12 | test_cases: 13 | - command: "бобук!" 14 | result: "^https:\\/\\/twitter\\.com\\/bobuk\\/status\\/\\d+$" 15 | 16 | - command: "!твит ksenks" 17 | result: "^https:\\/\\/twitter\\.com\\/ksenks\\/status\\/\\d+$" 18 | 19 | - command: "!твит tweetbotrt" 20 | result: "^https:\\/\\/twitter\\.com\\/tweetbotrt\\/status\\/1013416833884581888$" 21 | -------------------------------------------------------------------------------- /tweet-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | tweet-bot: 2 | build: . 3 | container_name: tweet-bot 4 | hostname: tweet-bot 5 | restart: always 6 | ports: 7 | - "8080:8080" -------------------------------------------------------------------------------- /tweet-bot/requirements.txt: -------------------------------------------------------------------------------- 1 | aiohttp==2.3.10 2 | tweepy==3.6.0 -------------------------------------------------------------------------------- /weather-bot/.dockerignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Gradle template 3 | .gradle 4 | /build 5 | 6 | # Ignore Gradle GUI config 7 | gradle-app.setting 8 | 9 | # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) 10 | !gradle-wrapper.jar 11 | 12 | # Cache of project 13 | .gradletasknamecache 14 | 15 | /.idea 16 | 17 | -------------------------------------------------------------------------------- /weather-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8 2 | 3 | RUN mkdir /tmp_b && \ 4 | mkdir /wb 5 | COPY . /tmp_b 6 | RUN chmod 777 /tmp_b/gradlew 7 | WORKDIR /tmp_b 8 | 9 | RUN ./gradlew -g /tmp_b/tmp build -Dorg.gradle.daemon=false 10 | RUN mv ./build/libs/weather-bot-0.1.jar /wb && \ 11 | rm -rf /tmp_b 12 | 13 | WORKDIR /wb 14 | 15 | EXPOSE 8080 16 | 17 | CMD ["java", "-jar", "weather-bot-0.1.jar"] 18 | -------------------------------------------------------------------------------- /weather-bot/README.md: -------------------------------------------------------------------------------- 1 | # Weather-bot (RU) 2 | Показывает текущую температуру и погоду в указанном городе 3 | 4 | ###Как использовать 5 | Нужно ввести команду !weather:city-name 6 | Название города должно быть **обязательно на английском языке** 7 | и содержать только буквы "A-z" (в любом регистре), " " (пробелы) или "-" (дефис) 8 | После префикса "!weather:" может идти сколько угодно пробелов, 9 | но название города обязательно должно начинаться с буквы 10 | и собержать как минимум два буквенных символа. 11 | Название не обязательно должно быть точным, 12 | в таком случае будут найдены данные для наиболее 13 | близкого по названию города (см. примеры) 14 | 15 | ###Пример 16 | Следующие запросы дадут одинаковый результат 17 | !weather:new-york 18 | !weather: New-York 19 | !weather:new york 20 | !weather:newyork 21 | !weather: ny 22 | 23 | Результат: 24 | **[New York](http://openweathermap.org/city/5128581) -2°C** 25 | Overcast clouds 26 | ![overcast clouds](http://openweathermap.org/img/w/04n.png) 27 | 28 | ###Дополнительно 29 | Замечания, предложения по работе данного бота можно оставлять [здесь](https://github.com/mylog00/rt-bot/issues) 30 | -------------------------------------------------------------------------------- /weather-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "weather-bot" 2 | bot_display_name: "weather-bot" 3 | 4 | defaults: 5 | username: "test_name" 6 | 7 | ignored_commands: 8 | - "some text" 9 | - "!weather: m " 10 | - "!weather: лондон " 11 | - "!weather: york 23 " 12 | - "!weather: -new york " 13 | 14 | test_cases: 15 | - command: "!weather:!status" 16 | result: "weather-bot work fine" 17 | -------------------------------------------------------------------------------- /weather-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | weather-bot: 2 | build: . 3 | ports: 4 | - "8080:8080" 5 | -------------------------------------------------------------------------------- /weather-bot/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/weather-bot/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /weather-bot/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Feb 05 12:26:09 MSK 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip 7 | -------------------------------------------------------------------------------- /weather-bot/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'weather-bot' 2 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/BotResponse.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot 2 | 3 | /** 4 | * @author Dmitrii Kniazev 5 | * @since 05.02.2017 6 | */ 7 | data class BotResponse(val text: String, 8 | val bot: String = Main.BOT_NAME) 9 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/Event.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot 2 | 3 | /** 4 | * @author Dmitrii Kniazev 5 | * @since 05.02.2017 6 | */ 7 | class Event { 8 | var text: String = "" 9 | var username: String = "" 10 | var display_name: String = "" 11 | } 12 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/openweather/Clouds.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot.openweather 2 | 3 | /** 4 | * @author Dmitrii Kniazev 5 | * @since 07.02.2017 6 | */ 7 | internal class Clouds { 8 | /**Cloudiness, %*/ 9 | var all: Int = 0 10 | } 11 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/openweather/Geolocation.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot.openweather 2 | 3 | /** 4 | * @author Dmitrii Kniazev 5 | * @since 07.02.2017 6 | */ 7 | internal class Geolocation { 8 | /**City geo location, longitude*/ 9 | var lon: Double = 0.0 10 | /**City geo location, latitude*/ 11 | var lat: Double = 0.0 12 | } 13 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/openweather/IWeatherService.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot.openweather 2 | 3 | import rt.bot.weatherbot.BotResponse 4 | 5 | /** 6 | * @author Dmitrii Kniazev 7 | * @since 06.02.2017 8 | */ 9 | interface IWeatherService { 10 | fun getWeather(cityName: String): BotResponse? 11 | } 12 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/openweather/Sys.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot.openweather 2 | 3 | /** 4 | * @author Dmitrii Kniazev 5 | * @since 07.02.2017 6 | */ 7 | internal class Sys { 8 | /**Internal parameter*/ 9 | var type: Int = 0 10 | /**Internal parameter*/ 11 | var id: Int = 0 12 | /**Internal parameter*/ 13 | var message: Double = 0.0 14 | /** Country code (GB, JP etc.)*/ 15 | var country: String? = null 16 | /**Sunrise time, unix, UTC*/ 17 | var sunrise: Long = 0 18 | /**Sunset time, unix, UTC*/ 19 | var sunset: Long = 0 20 | } 21 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/openweather/Weather.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot.openweather 2 | 3 | /** 4 | * @author Dmitrii Kniazev 5 | * @since 07.02.2017 6 | */ 7 | internal class Weather { 8 | /**Weather condition id*/ 9 | var id: Int = 0 10 | /**Group of weather parameters (Rain, Snow, Extreme etc.)*/ 11 | var main: String? = null 12 | /**Weather condition within the group*/ 13 | var description: String? = null 14 | /**Weather icon id*/ 15 | var icon: String? = null 16 | } 17 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/openweather/WeatherData.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot.openweather 2 | 3 | import java.util.Collections 4 | 5 | 6 | /** 7 | * @author Dmitrii Kniazev 8 | * @since 06.02.2017 9 | */ 10 | internal class WeatherData { 11 | /**City geo location*/ 12 | var coord: Geolocation? = null 13 | /**Weather type*/ 14 | var weather: List = Collections.emptyList() 15 | /**Internal parameter*/ 16 | var base: String? = null 17 | /**Weather metrics*/ 18 | var main: Metrics? = null 19 | /**Visibility, meter*/ 20 | var visibility: Int = 0 21 | /**Wind metrics*/ 22 | var wind: Wind? = null 23 | /**Cloudiness*/ 24 | var clouds: Clouds? = null 25 | /**Time of data calculation, unix, UTC*/ 26 | var dt: Long = 0 27 | /**System data*/ 28 | var sys: Sys? = null 29 | /**City ID*/ 30 | var id: Long = 0 31 | /**City name*/ 32 | var name: String = "Unknown" 33 | /**Internal parameter*/ 34 | var cod: Int = 0 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/openweather/Wind.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot.openweather 2 | 3 | /** 4 | * @author Dmitrii Kniazev 5 | * @since 07.02.2017 6 | */ 7 | internal class Wind { 8 | /**Wind speed. Unit Default: meter/sec*/ 9 | var speed: Double = 0.0 10 | /**Wind direction, degrees (meteorological)*/ 11 | var deg: Int = 0 12 | } 13 | -------------------------------------------------------------------------------- /weather-bot/src/main/kotlin/rt/bot/weatherbot/utils/StringUtils.kt: -------------------------------------------------------------------------------- 1 | package rt.bot.weatherbot.utils 2 | 3 | import rt.bot.weatherbot.Main 4 | 5 | /** 6 | * @author Dmitrii Kniazev 7 | * @since 10.02.2017 8 | */ 9 | object StringUtils { 10 | private val REGEX = Regex("[a-z][a-z -]*[a-z]") 11 | private val SPACE = Regex(" {2,}") 12 | private val DASH = Regex("-{2,}") 13 | 14 | fun trim(str: String?): String { 15 | if (str == null) return "" 16 | return str.trim() 17 | } 18 | 19 | fun parseRequest(reqStr: String): String { 20 | if (reqStr.startsWith(Main.PREFIX, true)) { 21 | val cityName = reqStr.drop(Main.PREFIX.length) 22 | .trim() 23 | .toLowerCase() 24 | .replace(SPACE, " ") 25 | .replace(DASH, "-") 26 | if (cityName.length > 1 && 27 | cityName.matches(REGEX)) { 28 | return cityName.replace(" ", "+") 29 | } 30 | } 31 | return "" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /weather-bot/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /weather-bot/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /wiki-bot/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM java:8-alpine 2 | MAINTAINER Mike Shemanskiy 3 | 4 | ENV M2_HOME=/usr/lib/mvn 5 | ENV M2=$M2_HOME/bin 6 | ENV PATH $PATH:$JAVA_HOME:$JAVA:$M2_HOME:$M2 7 | 8 | ADD http://ftp.fau.de/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.tar.gz /tmp/ 9 | 10 | RUN cd /tmp/ && \ 11 | tar -zxvf apache-maven-3.3.9-bin.tar.gz && \ 12 | rm apache-maven-3.3.9-bin.tar.gz && \ 13 | mv apache-maven-3.3.9 /usr/lib/mvn && \ 14 | rm -rf /tmp/* && \ 15 | mkdir -p /bot 16 | 17 | ADD . /src 18 | WORKDIR /bot 19 | 20 | RUN cd /src/ && mvn -q package \ 21 | && mv target/rtbot-0.0.1-SNAPSHOT.jar /bot \ 22 | && rm -rf /src /usr/lib/mvn /tmp/* 23 | 24 | EXPOSE 8080 25 | 26 | CMD ["java", "-jar", "rtbot-0.0.1-SNAPSHOT.jar"] 27 | -------------------------------------------------------------------------------- /wiki-bot/README.md: -------------------------------------------------------------------------------- 1 | # Radio-t wiki bot 2 | 3 | write chat message: **wiki json** 4 | 5 | https://bot.radio-t.com/api/wiki-bot/event?text=wiki%20json&username=mike&display_name=shem 6 | 7 | return url to russian wiki: **https://ru.wikipedia.org/wiki/JSON** 8 | 9 | if no result, return: **I don't know, ask Bobuk!** 10 | 11 | **Usecase:** when you hear "strange" buzzword like DNS, akka, etc., type **wiki akka** Infact wiki search not good, and maybe better show top3 urls from result set, but now only first. 12 | -------------------------------------------------------------------------------- /wiki-bot/bot-spec.yml: -------------------------------------------------------------------------------- 1 | bot_name: "wiki-bot" 2 | 3 | defaults: 4 | username: "test-user" 5 | display_name: "Test User" 6 | 7 | ignored_commands: 8 | - "Ignored message 1" 9 | - "Ignored message 2" 10 | - "Ignored message 3" 11 | 12 | test_cases: 13 | - command: "wiki qweasdqwe" 14 | result: "I don't know, ask Bobuk!" 15 | 16 | - command: "wiki http" 17 | result: "https://ru.wikipedia.org/wiki/HTTP" 18 | 19 | - command: "wiki hello world" 20 | result: "https://ru.wikipedia.org/wiki/Hello,_world!" -------------------------------------------------------------------------------- /wiki-bot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | rt-wiki-bot: 2 | build: . 3 | ports: 4 | - "8080:8080" -------------------------------------------------------------------------------- /wiki-bot/src/main/java/com/m11/Bot.java: -------------------------------------------------------------------------------- 1 | package com.m11; 2 | 3 | public class Bot { 4 | public String text; 5 | 6 | public String username; 7 | 8 | public String display_name; 9 | 10 | public Bot() {} 11 | 12 | public String getText() { 13 | return text; 14 | } 15 | 16 | public String getUsername() { 17 | return username; 18 | } 19 | 20 | public String getDisplay_name() { 21 | return display_name; 22 | } 23 | 24 | @Override 25 | public String toString() { 26 | return "Bot{" + 27 | "text='" + text + '\'' + 28 | ", username='" + username + '\'' + 29 | ", display_name='" + display_name + '\'' + 30 | '}'; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /wiki-bot/src/main/java/com/m11/RtbotApplication.java: -------------------------------------------------------------------------------- 1 | package com.m11; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class RtbotApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(RtbotApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /wiki-bot/src/test/java/com/m11/RtbotApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.m11; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class RtbotApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /wiki-bot/src/test/java/com/m11/WikiHandlerTest.java: -------------------------------------------------------------------------------- 1 | package com.m11; 2 | 3 | import org.junit.Assert; 4 | import org.junit.BeforeClass; 5 | import org.junit.Test; 6 | 7 | public class WikiHandlerTest { 8 | 9 | private static WikiHandler wikiHandler; 10 | 11 | @BeforeClass 12 | public static void setUp(){ 13 | wikiHandler = new WikiHandler(); 14 | } 15 | 16 | @Test 17 | public void emptyUrl() throws Exception { 18 | 19 | 20 | 21 | String empty = wikiHandler.getWikiUrl(""); 22 | 23 | Assert.assertEquals("", empty); 24 | 25 | String empty2 = wikiHandler.getWikiUrl("wiki "); 26 | 27 | Assert.assertEquals("", empty2); 28 | } 29 | 30 | @Test 31 | public void validUrl() throws Exception { 32 | 33 | String validUrl = wikiHandler.getWikiUrl("wikibarak obama"); 34 | 35 | Assert.assertNotNull(validUrl); 36 | 37 | String validUrl2 = wikiHandler.getWikiUrl("barak obama"); 38 | 39 | Assert.assertNotNull(validUrl2); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /wiki-bot/target/classes/com/m11/Bot.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/wiki-bot/target/classes/com/m11/Bot.class -------------------------------------------------------------------------------- /wiki-bot/target/classes/com/m11/RtbotApplication.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/wiki-bot/target/classes/com/m11/RtbotApplication.class -------------------------------------------------------------------------------- /wiki-bot/target/classes/com/m11/RtbotController.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/wiki-bot/target/classes/com/m11/RtbotController.class -------------------------------------------------------------------------------- /wiki-bot/target/classes/com/m11/WikiHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/wiki-bot/target/classes/com/m11/WikiHandler.class -------------------------------------------------------------------------------- /wiki-bot/target/maven-archiver/pom.properties: -------------------------------------------------------------------------------- 1 | #Generated by Apache Maven 2 | #Mon Nov 07 21:09:15 EET 2016 3 | version=0.0.1-SNAPSHOT 4 | groupId=com.m11 5 | artifactId=rtbot 6 | -------------------------------------------------------------------------------- /wiki-bot/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst: -------------------------------------------------------------------------------- 1 | com/m11/RtbotApplication.class 2 | com/m11/WikiHandler.class 3 | com/m11/RtbotController.class 4 | com/m11/Bot.class 5 | -------------------------------------------------------------------------------- /wiki-bot/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /home/mike/Dev/rtbot/src/main/java/com/m11/RtbotApplication.java 2 | /home/mike/Dev/rtbot/src/main/java/com/m11/Bot.java 3 | /home/mike/Dev/rtbot/src/main/java/com/m11/WikiHandler.java 4 | /home/mike/Dev/rtbot/src/main/java/com/m11/RtbotController.java 5 | -------------------------------------------------------------------------------- /wiki-bot/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst: -------------------------------------------------------------------------------- 1 | com/m11/RtbotApplicationTests.class 2 | com/m11/WikiHandlerTest.class 3 | -------------------------------------------------------------------------------- /wiki-bot/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst: -------------------------------------------------------------------------------- 1 | /home/mike/Dev/rtbot/src/test/java/com/m11/WikiHandlerTest.java 2 | /home/mike/Dev/rtbot/src/test/java/com/m11/RtbotApplicationTests.java 3 | -------------------------------------------------------------------------------- /wiki-bot/target/rtbot-0.0.1-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/wiki-bot/target/rtbot-0.0.1-SNAPSHOT.jar -------------------------------------------------------------------------------- /wiki-bot/target/rtbot-0.0.1-SNAPSHOT.jar.original: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/wiki-bot/target/rtbot-0.0.1-SNAPSHOT.jar.original -------------------------------------------------------------------------------- /wiki-bot/target/surefire-reports/com.m11.RtbotApplicationTests.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Test set: com.m11.RtbotApplicationTests 3 | ------------------------------------------------------------------------------- 4 | Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.533 sec - in com.m11.RtbotApplicationTests 5 | -------------------------------------------------------------------------------- /wiki-bot/target/surefire-reports/com.m11.WikiHandlerTest.txt: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------- 2 | Test set: com.m11.WikiHandlerTest 3 | ------------------------------------------------------------------------------- 4 | Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec - in com.m11.WikiHandlerTest 5 | -------------------------------------------------------------------------------- /wiki-bot/target/test-classes/com/m11/RtbotApplicationTests.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/wiki-bot/target/test-classes/com/m11/RtbotApplicationTests.class -------------------------------------------------------------------------------- /wiki-bot/target/test-classes/com/m11/WikiHandlerTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/radio-t/rt-bot/6ee5f955e908b1de5d0f996f36591ac7409b4bf4/wiki-bot/target/test-classes/com/m11/WikiHandlerTest.class --------------------------------------------------------------------------------