scriptorium 0.0.3 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.lt3 +324 -0
- data/README.md +3155 -1
- data/assets/.DS_Store +0 -0
- data/assets/README.md +44 -0
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/icons/ui/.DS_Store +0 -0
- data/assets/icons/ui/back.png +0 -0
- data/assets/icons/ui/copy.png +0 -0
- data/assets/icons/ui/down.png +0 -0
- data/assets/icons/ui/end.png +0 -0
- data/assets/icons/ui/exit.png +0 -0
- data/assets/icons/ui/foo +10 -0
- data/assets/icons/ui/home.png +0 -0
- data/assets/icons/ui/left.png +0 -0
- data/assets/icons/ui/next.png +0 -0
- data/assets/icons/ui/right.png +0 -0
- data/assets/icons/ui/start.png +0 -0
- data/assets/icons/ui/up.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +94 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +2 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +45 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +35 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +27 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
- data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
- data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
- data/doc/banner_svg_config.md +114 -0
- data/doc/contrib.lt3 +8 -0
- data/doc/dependencies.md +281 -0
- data/doc/hacker.lt3 +5 -0
- data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
- data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
- data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
- data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
- data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
- data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
- data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
- data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
- data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
- data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
- data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
- data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
- data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
- data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
- data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
- data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
- data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
- data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
- data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
- data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
- data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
- data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
- data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
- data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
- data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
- data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
- data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
- data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
- data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
- data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
- data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
- data/doc/imported/0018-ruby-puns/post.html +46 -0
- data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
- data/doc/imported/0020-fffff/metadata.txt +7 -0
- data/doc/imported/0020-fffff/post.html +24 -0
- data/doc/imported/0020-fffff/source.lt3 +12 -0
- data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
- data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
- data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
- data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
- data/doc/imported/0023-doctor-sleep/post.html +63 -0
- data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
- data/doc/imported/0024-just-a-test/metadata.txt +7 -0
- data/doc/imported/0024-just-a-test/post.html +24 -0
- data/doc/imported/0024-just-a-test/source.lt3 +12 -0
- data/doc/imported/import_summary.txt +98 -0
- data/doc/livetext-informal-spec.txt +65 -0
- data/doc/myuserdoc/ch-0.lt3 +31 -0
- data/doc/myuserdoc/ch-1.lt3 +37 -0
- data/doc/myuserdoc/ch-10.lt3 +22 -0
- data/doc/myuserdoc/ch-2.lt3 +37 -0
- data/doc/myuserdoc/ch-3.lt3 +19 -0
- data/doc/myuserdoc/ch-4.lt3 +43 -0
- data/doc/myuserdoc/ch-5.lt3 +22 -0
- data/doc/myuserdoc/ch-6.lt3 +19 -0
- data/doc/myuserdoc/ch-7.lt3 +16 -0
- data/doc/myuserdoc/ch-8.lt3 +13 -0
- data/doc/myuserdoc/ch-9.lt3 +19 -0
- data/doc/myuserdoc/tweak.rb +18 -0
- data/doc/myuserdoc/userdoc-toc.txt +88 -0
- data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
- data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
- data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
- data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
- data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
- data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
- data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
- data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
- data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
- data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
- data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
- data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
- data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
- data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
- data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
- data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
- data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
- data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
- data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
- data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
- data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
- data/doc/old-posts/0024-just-a-test.lt3 +12 -0
- data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
- data/doc/old-repo +1 -0
- data/doc/reddit_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +35 -0
- data/doc/user_guide_section_1.md +137 -0
- data/doc/user_guide_section_10.md +515 -0
- data/doc/user_guide_section_11.md +708 -0
- data/doc/user_guide_section_2.md +233 -0
- data/doc/user_guide_section_3.md +5 -0
- data/doc/user_guide_section_4.md +221 -0
- data/doc/user_guide_section_5.md +243 -0
- data/doc/user_guide_section_6.md +147 -0
- data/doc/user_guide_section_7.md +311 -0
- data/doc/user_guide_section_8.md +224 -0
- data/doc/user_guide_section_9.md +375 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +2373 -0
- data/lib/scriptorium/banner_svg.rb +729 -0
- data/lib/scriptorium/contract.rb +34 -0
- data/lib/scriptorium/exceptions.rb +201 -1
- data/lib/scriptorium/helpers.rb +675 -0
- data/lib/scriptorium/post.rb +259 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +938 -0
- data/lib/scriptorium/standard_files.rb +149 -0
- data/lib/scriptorium/support/bootstrap/css.txt +5 -0
- data/lib/scriptorium/support/bootstrap/js.txt +4 -0
- data/lib/scriptorium/support/common_js/clipboard.js +35 -0
- data/lib/scriptorium/support/common_js/content-loader.js +187 -0
- data/lib/scriptorium/support/common_js/navigation.js +52 -0
- data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
- data/lib/scriptorium/support/config/reddit.txt +10 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/lib/scriptorium/support/config/social.txt +8 -0
- data/lib/scriptorium/support/highlight/css.txt +2 -0
- data/lib/scriptorium/support/highlight/custom.css +119 -0
- data/lib/scriptorium/support/highlight/js.txt +1 -0
- data/lib/scriptorium/support/post_index/config.txt +15 -0
- data/lib/scriptorium/support/post_index/style.css +55 -0
- data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
- data/lib/scriptorium/support/templates/initial_post.lt3 +12 -0
- data/lib/scriptorium/support/templates/layout.txt +5 -0
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/lib/scriptorium/support/theme/footer.lt3 +2 -0
- data/lib/scriptorium/support/theme/header.lt3 +4 -0
- data/lib/scriptorium/support/theme/left.lt3 +3 -0
- data/lib/scriptorium/support/theme/main.lt3 +5 -0
- data/lib/scriptorium/support/theme/right.lt3 +3 -0
- data/lib/scriptorium/theme.rb +192 -0
- data/lib/scriptorium/version.rb +1 -1
- data/lib/scriptorium/view.rb +1021 -0
- data/lib/scriptorium/widgets/featured_posts.rb +149 -0
- data/lib/scriptorium/widgets/links.rb +112 -0
- data/lib/scriptorium/widgets/pages.rb +133 -0
- data/lib/scriptorium/widgets/widget.rb +133 -0
- data/lib/scriptorium.rb +38 -34
- data/lib/skeleton.rb +10 -1
- data/scriptorium.gemspec +17 -5
- data/test/README.md +69 -0
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +83 -0
- data/test/api_demo.rb +99 -0
- data/test/assets/imagenotfound.jpg +0 -0
- data/test/assets/images/.DS_Store +0 -0
- data/test/assets/images/README.md +27 -0
- data/test/assets/images/odd_aspect.png +0 -0
- data/test/assets/images/perfect.png +0 -0
- data/test/assets/images/small.png +0 -0
- data/test/assets/images/tall.png +0 -0
- data/test/assets/images/very_tall.png +0 -0
- data/test/assets/images/very_wide.png +0 -0
- data/test/assets/images/wide.png +0 -0
- data/test/assets/testbanner.jpg +0 -0
- data/test/banner_svg/simple_helpers.rb +13 -0
- data/test/banner_svg/unit.rb +1000 -0
- data/test/config/deployment.txt +5 -0
- data/test/ed_test.rb +204 -0
- data/test/integration/cursor_banner_combinations.rb +193 -0
- data/test/integration/cursor_banner_features.rb +374 -0
- data/test/integration/integration_test.rb +326 -0
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +500 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/svg.txt +3 -0
- data/test/manual/banner-tests/test01.html +122 -0
- data/test/manual/banner-tests/test02.html +122 -0
- data/test/manual/banner-tests/test03.html +122 -0
- data/test/manual/banner-tests/test04.html +129 -0
- data/test/manual/banner-tests/test05.html +129 -0
- data/test/manual/banner-tests/test06.html +129 -0
- data/test/manual/banner-tests/test07.html +129 -0
- data/test/manual/banner-tests/test08.html +123 -0
- data/test/manual/banner-tests/test09.html +123 -0
- data/test/manual/banner-tests/test10.html +123 -0
- data/test/manual/banner-tests/test11.html +123 -0
- data/test/manual/banner-tests/test12.html +123 -0
- data/test/manual/banner-tests/test13.html +123 -0
- data/test/manual/banner-tests/test14.html +123 -0
- data/test/manual/banner-tests/test15.html +122 -0
- data/test/manual/banner-tests/test16.html +122 -0
- data/test/manual/banner-tests/test17.html +122 -0
- data/test/manual/banner-tests/test18.html +132 -0
- data/test/manual/banner-tests/test19.html +132 -0
- data/test/manual/banner-tests/test20.html +132 -0
- data/test/manual/banner-tests/test21.html +132 -0
- data/test/manual/banner-tests/test22.html +132 -0
- data/test/manual/banner-tests/test23.html +132 -0
- data/test/manual/banner-tests/test24.html +132 -0
- data/test/manual/banner-tests/test25.html +131 -0
- data/test/manual/banner_environment.rb +205 -0
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/test_advanced_widgets.rb +73 -0
- data/test/manual/test_banner_combinations.rb +120 -0
- data/test/manual/test_banner_features.rb +306 -0
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_basic_posts.rb +47 -0
- data/test/manual/test_layout_widgets.rb +40 -0
- data/test/manual/test_pagination.rb +24 -0
- data/test/manual/test_random_posts.rb +38 -0
- data/test/manual/test_syntax_highlighting.rb +167 -0
- data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
- data/test/rubytext/rubytext_demo_test.rb +42 -0
- data/test/rubytext/rubytext_testing_guide.md +277 -0
- data/test/run_automated_tests.rb +45 -0
- data/test/staging/.DS_Store +0 -0
- data/test/support/preview_utils.rb +88 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +240 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +883 -0
- data/test/unit/api.rb +1776 -0
- data/test/unit/asset_management.rb +219 -0
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +69 -0
- data/test/unit/core.rb +1211 -0
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +478 -0
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +183 -0
- data/test/unit/livetext_basic.rb +57 -0
- data/test/unit/livetext_compatibility.rb +82 -0
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/permalink_copy_test.rb +211 -0
- data/test/unit/post.rb +309 -0
- data/test/unit/post_index_config_test.rb +258 -0
- data/test/unit/post_state_helpers_test.rb +137 -0
- data/test/unit/read_commented_file_test.rb +278 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +569 -0
- data/test/unit/social_test.rb +366 -0
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +498 -0
- data/test/unit/widgets.rb +669 -0
- data/test/web_integration_test.rb +231 -0
- data/test/web_test_helper.rb +218 -0
- data/test/web_workflow_test.rb +527 -0
- data/test/wizard_test.rb +123 -0
- data/ui/README.md +67 -0
- data/ui/common/lib/ui_common.rb +8 -0
- data/ui/rubytext/README.md +191 -0
- data/ui/rubytext/bin/scriptorium-rubytext +402 -0
- data/ui/rubytext/lib/rubytext_ui.rb +300 -0
- data/ui/tui/bin/scriptorium +1890 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +2600 -0
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +196 -0
- data/ui/web/app/views/asset_management.erb +645 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +154 -0
- data/ui/web/app/views/deploy_config.erb +149 -0
- data/ui/web/app/views/edit_pages.erb +363 -0
- data/ui/web/app/views/edit_post.erb +175 -0
- data/ui/web/app/views/edit_theme.erb +73 -0
- data/ui/web/app/views/edit_theme_file.erb +74 -0
- data/ui/web/app/views/error_page.erb +29 -0
- data/ui/web/app/views/header_config.erb +155 -0
- data/ui/web/app/views/layout_config.erb +147 -0
- data/ui/web/app/views/navbar_config.erb +411 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +779 -0
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +164 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -0
- metadata +434 -8
- data/lib/scriptorium/engine.rb +0 -22
- data/test/engine/unit.rb +0 -44
@@ -0,0 +1,129 @@
|
|
1
|
+
.post 17
|
2
|
+
|
3
|
+
.title The Forgotten Mathematician
|
4
|
+
.pubdate 2019-12-25
|
5
|
+
.views computing
|
6
|
+
.tags
|
7
|
+
|
8
|
+
.pin computing
|
9
|
+
|
10
|
+
.teaser
|
11
|
+
We all know his name... but many of us only "sort of" know it.
|
12
|
+
.end
|
13
|
+
|
14
|
+
.dropcap
|
15
|
+
We all remember Boole in our own way, if at all. His work comes up in discrete
|
16
|
+
math and in electrical engineering, among other places. But computer science students and
|
17
|
+
programmers in general remember him chiefly for the Boolean operators and the concept of the
|
18
|
+
Boolean data type.
|
19
|
+
.end
|
20
|
+
|
21
|
+
.set dash=—
|
22
|
+
|
23
|
+
I decided to Google for "who was Boole"... this was the result.
|
24
|
+
|
25
|
+
.image gooboo.png
|
26
|
+
|
27
|
+
|
28
|
+
Notice the top autocomplete. This seems to suggest that "Boolean" was the person's name. I
|
29
|
+
decided to make this blog post to set the record straight.
|
30
|
+
|
31
|
+
But that isn't the only reason I'm writing this. I want to speak up for this historical figure
|
32
|
+
just a little and correct what I perceive as a minor injustice.
|
33
|
+
|
34
|
+
Did anything look unusual in the previous sentences? Perhaps the capitalization of "Boolean"?
|
35
|
+
It's often lowercased in the computing community, and there are reasonable historical reasons
|
36
|
+
for this.
|
37
|
+
|
38
|
+
In the old days, it was often inconvenient or impossible to type or even to render lowercase
|
39
|
+
letters. As recently as the 1980s, I have seen terminals and printers that were strictly uppercase.
|
40
|
+
Take a look at a textbook or manual from that era, and you will often see the same thing.
|
41
|
+
|
42
|
+
On the other hand, people have always known that in English and similar languages, lowercase was
|
43
|
+
an essential part of reality. As it became practical to use computers for applications such as
|
44
|
+
typesetting and word processing, we started to take mixed case for granted.
|
45
|
+
|
46
|
+
Somewhere in this time frame (or a little earlier), UNIX came along. And yes, we did spell it
|
47
|
+
in all caps at the time. This was true of most computer language names and such, many of which
|
48
|
+
were some kind of acronym or abbreviation: FORTRAN, COBOL, BASIC. There was no particular reason
|
49
|
+
to put PASCAL in all caps... but people often did, out of a strange kind of habit.
|
50
|
+
|
51
|
+
But let's get back to UNIX. Have you ever wondered why we type ``ls, ``cp, and `mv rather than
|
52
|
+
``list, ``copy, and `[move]? It's not just that old terminals could be slow to echo. One of the
|
53
|
+
UNIX creators basically _[hated to type]. (I remember it as Brian Kernighan, but it may have been
|
54
|
+
Thompson or Ritchie.) And I argue this laziness also extended to a reluctance to type capital letters.
|
55
|
+
Can you think of a command flag that is capitalized (such as `[-F]) _except where the lowercase
|
56
|
+
(such as `[-f]) was already used by something more fundamental? I can't think of one.
|
57
|
+
|
58
|
+
So as we made a transition from all-caps to mixed case, programming languages that were traditionally
|
59
|
+
written in upper case were now written in all lower case. In Pascal, we might once have written
|
60
|
+
`[FOR I:=1 TO 10], but a little later, we wrote `[for i:=1 to 10] instead.
|
61
|
+
|
62
|
+
Do you see where this is going? Where we once wrote ``BOOLEAN, we wrote `boolean instead. And
|
63
|
+
because we saw this so often in our programs, we started writing it that way when we wrote _about
|
64
|
+
our programs.
|
65
|
+
|
66
|
+
Sometimes this is necessary. If you are using a language where identifiers are case-sensitive (like
|
67
|
+
most or all modern languages), there may well be an actual data type named ``boolean, and it would
|
68
|
+
be an error to capitalize it (even outside our code).
|
69
|
+
|
70
|
+
So typography matters here. For many years we have tended to write code in some kind of monospaced
|
71
|
+
typeface, harking back to the days when we had no choice in the matter. So consider these three
|
72
|
+
sentences, which might appear in any manual or piece of documentation:
|
73
|
+
|
74
|
+
.nlist
|
75
|
+
This function takes a `boolean parameter.
|
76
|
+
This function takes a boolean parameter.
|
77
|
+
This function takes a Boolean parameter.
|
78
|
+
.end
|
79
|
+
|
80
|
+
It's reasonable to use lowercase in (1), because we're presumably referring to an actual identifier
|
81
|
+
or reserved word in some language. As for (2) $dash I think we see that all the time, but I'm arguing
|
82
|
+
here it's not appropriate. The usage in (3) is more appropriate.
|
83
|
+
|
84
|
+
Now, before I am misunderstood and/or flamed $dash here are the things I am _not saying:
|
85
|
+
|
86
|
+
.list
|
87
|
+
I'm not saying we should change the compilers or interpreters.
|
88
|
+
I'm not saying that all the books and manuals should be rewritten.
|
89
|
+
I'm not saying you're ignorant or a bad person if you don't capitalize "Boolean."
|
90
|
+
I'm not saying we should call out people who don't capitalize it.
|
91
|
+
.end
|
92
|
+
|
93
|
+
But for comparison, let's look at some other scientists and mathematicians whose names have been
|
94
|
+
converted to adjectives. So far I have searched for these: Einsteinian, Newtonian, Galilean,
|
95
|
+
Ptolemaic, Copernican, Wronskian, Laplacian, Lagrangian, Riemannian, Euclidean, Keplerian,
|
96
|
+
Gaussian, Hamiltonian, Archimedean, Diophantine, Pythagorean, Darwinian, Lamarckian, Eulerian,
|
97
|
+
Cartesian, Napierian, Bayesian, and Brownian.
|
98
|
+
|
99
|
+
These terms have this in common: They are _[always capitalized]. (Interestingly, _Abelian seems
|
100
|
+
to be an exception in many people's usage.) And yes, you may find places where these names are
|
101
|
+
_not given capital letters, but I contend they are very few in number.
|
102
|
+
|
103
|
+
Let's range further afield, into the realms of philosophers, religious figures, writers, and
|
104
|
+
artists. I have searched for these: Socratic, Aristotelian, Mosaic, Benedictine, Kafkaesque,
|
105
|
+
Epicurean, Shakespearean, Elizabethan, Edwardian, Spenserian, Petrarchan, Smithsonian, Botticellian,
|
106
|
+
Dickensian, Orwellian, Jungian, Freudian, and Adlerian. I've found very few uncapitalized
|
107
|
+
names. The lowercased _kafkaesque is not unheard of, and we may informally call someone an
|
108
|
+
_epicurean (though we refer specifically to the _Epicurean philosophers in uppercase).
|
109
|
+
|
110
|
+
It's worth noting that units of measure named after people are not capitalized:
|
111
|
+
newton, ampere, coulomb, gauss, fermi, kelvin, henry, hertz, pascal, and watt. I can't find an
|
112
|
+
exception to this. Sometimes, though, the person's name is tacked on as _part of the unit or
|
113
|
+
system of measure; we do capitalize the names when we refer to degrees Fahrenheit, degrees
|
114
|
+
Celsius, Richter scale, Mohs scale, and the Dobson unit.
|
115
|
+
|
116
|
+
Of course, in many cases, we just don't convert a name to a different form: Hilbert space,
|
117
|
+
Schwarzschild radius, Feynmann diagram, Bohr model, Fermi principle, Drake equation, Rohrschach
|
118
|
+
test, Hall effect, and so on. Why is this so common? I think it's because an adjective form
|
119
|
+
might often be hard to spell or pronounce, and overall we have less of a tendency for "fancy"
|
120
|
+
adjectives nowadays. But in any event, we'd never think of lowercasing these names.
|
121
|
+
|
122
|
+
And yet Boole is shortchanged so often in our world! Mathematicians talk about Boolean algebra,
|
123
|
+
and even electrical engineers talk of Boolean logic; but programmers talk of _boolean data and
|
124
|
+
_boolean operators.
|
125
|
+
|
126
|
+
Come on, guys. Give him his due. By the way, his first name was George.
|
127
|
+
|
128
|
+
So I am making a pledge: Where it's possible and practical, I will capitalize _Boolean whenever
|
129
|
+
I write an article, a book, or a piece of documentation. I encourage you to do the same.
|
@@ -0,0 +1,31 @@
|
|
1
|
+
.post 18
|
2
|
+
|
3
|
+
.title Ruby puns
|
4
|
+
.pubdate 2020-01-21
|
5
|
+
.views computing computing
|
6
|
+
.tags
|
7
|
+
|
8
|
+
.teaser
|
9
|
+
These are pretty bad. You've been warned.
|
10
|
+
.end
|
11
|
+
|
12
|
+
|
13
|
+
.mono
|
14
|
+
cheese = "" # String cheese
|
15
|
+
browns = {} # Hash browns
|
16
|
+
hiphip = [] # hiphip array
|
17
|
+
case; end # brief case
|
18
|
+
foods.freeze # frozen foods
|
19
|
+
love.taint # tainted love
|
20
|
+
attr_writer :irish # Irish setter
|
21
|
+
{"corned" => "beef"} # corned beef hash
|
22
|
+
raise "hell" # raising hell
|
23
|
+
$village # global village
|
24
|
+
|
25
|
+
usual_suspects = 1.99
|
26
|
+
usual_suspects.ceil # round up the usual suspects
|
27
|
+
|
28
|
+
class JesusChrist < God
|
29
|
+
super(*) # Jesus Christ Superstar
|
30
|
+
end
|
31
|
+
.end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
.post 19
|
2
|
+
|
3
|
+
.mixin code_rouge
|
4
|
+
|
5
|
+
.title Custom exceptions via metaprogramming
|
6
|
+
.pubdate 2020-02-17
|
7
|
+
.views computing computing
|
8
|
+
.tags
|
9
|
+
|
10
|
+
.teaser
|
11
|
+
Suppose you want a large number of custom exceptions. And suppose you're not afraid of metaprogramming.
|
12
|
+
.end
|
13
|
+
|
14
|
+
A few months back, I found myself wanting to be "more specific" with the exceptions
|
15
|
+
I raised in my ongoing RuneBlog project (which is used to create this blog). I
|
16
|
+
wanted to raise specific exceptions with custom parameterized messages (without
|
17
|
+
repeating myself too much).
|
18
|
+
|
19
|
+
Here's an example of the "usual" way to do this:
|
20
|
+
|
21
|
+
.ruby
|
22
|
+
class MyException < StandardError
|
23
|
+
|
24
|
+
def initialize(file, dir)
|
25
|
+
msg = "Could not find #{file} under #{dir}"
|
26
|
+
super(msg)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
raise MyException.new("stuff.txt", "/home/willard")
|
32
|
+
|
33
|
+
# Output:
|
34
|
+
# exc.rb:10:in `<main>': Could not find stuff.txt under /home/willard (MyException)
|
35
|
+
.end
|
36
|
+
|
37
|
+
Now there is nothing particularly wrong with that. But as it happens, I wanted a
|
38
|
+
large number of exceptions with fairly descriptive names. I didn't want to type
|
39
|
+
(or even paste) this stuff over and over.
|
40
|
+
|
41
|
+
Here comes the "not afraid of metaprogramming" part. This is what I did:
|
42
|
+
|
43
|
+
.ruby
|
44
|
+
def make_exception(sym, str, target_class = Object)
|
45
|
+
return if target_class.constants.include?(sym)
|
46
|
+
target_class.const_set(sym, StandardError.dup)
|
47
|
+
define_method(sym) do |*args|
|
48
|
+
msg = str.dup
|
49
|
+
args.each.with_index {|arg, i| msg.sub!("%#{i+1}", arg) }
|
50
|
+
target_class.class_eval(sym.to_s).new(msg)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
.end
|
54
|
+
|
55
|
+
Now, what does this do? The method takes two parameters (or three if you count the
|
56
|
+
target class which defaults to `[Object]). You specify a symbol (for the
|
57
|
+
name of the exception) and a string (for the exception message). It then does
|
58
|
+
two things: It creates an exception class (named after the symbol); and it creates
|
59
|
+
a method of the same name.
|
60
|
+
|
61
|
+
Here are examples of calling `[make_exception]:
|
62
|
+
|
63
|
+
.ruby
|
64
|
+
make_exception(:NotImplemented, "Feature not yet implemented")
|
65
|
+
make_exception(:CantOpen, "Can't open '%1'")
|
66
|
+
make_exception(:InternalError, "Internal error: Method %1 got arg '%2'")
|
67
|
+
.end
|
68
|
+
|
69
|
+
And here are examples of raising these exceptions:
|
70
|
+
|
71
|
+
.ruby
|
72
|
+
raise NotImplemented
|
73
|
+
raise CantOpen(somefile)
|
74
|
+
raise InternalError(__method__, arg)
|
75
|
+
.end
|
76
|
+
|
77
|
+
You might ask: Why define a method returning an exception object? The answer
|
78
|
+
is that I don't want to write these this way:
|
79
|
+
|
80
|
+
.ruby
|
81
|
+
raise NotImplemented.new("Feature not yet implemented")
|
82
|
+
raise CantOpen.new("Can't open '#{somefile}'")
|
83
|
+
raise InternalError.new("Internal error: Method #{__method__} got arg '#{arg}'")
|
84
|
+
.end
|
85
|
+
|
86
|
+
I perceive four advantages doing it the first way: I don't have to specify the
|
87
|
+
message string each time; I still get to have a descriptive, unique class name
|
88
|
+
without the message making it seem redundantly; I don't have to interpolate
|
89
|
+
values into the message string explicitly; and I don't have to say `[.new]
|
90
|
+
every time.
|
91
|
+
|
92
|
+
Some of you may have two questions: Can you (or should you) really have a
|
93
|
+
capitalized method name? Can a method have the same name as a class without
|
94
|
+
confusing the interpreter?
|
95
|
+
|
96
|
+
I'll answer both those questions with an example from the Ruby core: There
|
97
|
+
is an `Integer class and an `Integer method (naturally related to each other).
|
98
|
+
Ruby distinguishes between these by context. It's not impossible, and I argue
|
99
|
+
it's not a bad practice.
|
100
|
+
|
101
|
+
As for the parameters, it's intuitive how they work. A `% sign signals a
|
102
|
+
numbered replaceable piece of text, and these are replaced with the parameters
|
103
|
+
specified when the method is called.
|
104
|
+
|
105
|
+
That part of the code is not really robust, by the way. As it is written now,
|
106
|
+
you could easily confuse it-- make it misbehave or crash. But you get the idea.
|
107
|
+
|
108
|
+
So far, I have defined 23 custom exceptions in this project. Each definition
|
109
|
+
occupies a single line. If I want to change the behavior of all of them in
|
110
|
+
some way, I will go and change the `make_exception method (which itself is
|
111
|
+
only 9 lines).
|
112
|
+
|
113
|
+
Like it, hate it? Comments welcome.
|
114
|
+
|
115
|
+
|
116
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
.post 21
|
2
|
+
|
3
|
+
.title Trying ROR yet again
|
4
|
+
.pubdate 2020-06-15
|
5
|
+
.views computing
|
6
|
+
.tags
|
7
|
+
|
8
|
+
.teaser
|
9
|
+
Those who know me know I'm not a Rails guy.
|
10
|
+
.end
|
11
|
+
|
12
|
+
I don't hate Rails, honestly. It's more that I hate web development
|
13
|
+
in general.
|
14
|
+
|
15
|
+
But here I am, trying once again to master the rudiments. Not because I
|
16
|
+
want jobs in that area, but because I want certain small projects built;
|
17
|
+
and I can't spend $100 an hour (or is it more?) to have someone else
|
18
|
+
do them.
|
19
|
+
|
20
|
+
To that end, last night I dived into _[Agile Web Development with Rails 6].
|
21
|
+
I covered about 156 pages and highighted passages in iBooks.
|
22
|
+
|
23
|
+
Admittedly, I skimmed over the "Ruby review" section pretty quickly, as I'm
|
24
|
+
supposed to know that stuff. But I still ran across something that made me
|
25
|
+
do a doubletake-- it was this line:
|
26
|
+
|
27
|
+
`[ class CreateProducts < ActiveRecord::Migration\[6.0\]]
|
28
|
+
|
29
|
+
The "versioned class" thing was new to me. I haven't looked it up yet, but
|
30
|
+
I assume `Migration is a hash of classes with version numbers as keys (faked
|
31
|
+
by `Float values). This is kind of an interesting concept, and it made my
|
32
|
+
mind go off in twelve different directions (as it often does at 3:15 in the
|
33
|
+
morning).
|
34
|
+
|
35
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
.post 23
|
2
|
+
|
3
|
+
.title Doctor Sleep
|
4
|
+
.pubdate 2020-11-07
|
5
|
+
.views chiller
|
6
|
+
.tags
|
7
|
+
|
8
|
+
.teaser
|
9
|
+
If you didn't know, this is the sequel to _[The Shining].
|
10
|
+
|
11
|
+
.end
|
12
|
+
|
13
|
+
I have to say: It was well done. It's not a Kubrick movie (and there will
|
14
|
+
never be another one), but in its own way, it's faithful enough to the
|
15
|
+
original.
|
16
|
+
|
17
|
+
What do you get with a Stephen King story? Well, let's be honest. He is a
|
18
|
+
little too good for the stuff he writes. He himself said, "I am the literary
|
19
|
+
equivalent of a burger and fries." And he isn't wrong.
|
20
|
+
|
21
|
+
But on the other hand, his characters are wonderfully three-dimensional.
|
22
|
+
(To be honest, I'm quoting someone who taught a writing seminar I was in
|
23
|
+
years ago. But it's spot on.) He is a master of characterization and dialogue,
|
24
|
+
of plotting and pacing, and his use of language sometimes rises to the realm
|
25
|
+
of the sublime.
|
26
|
+
|
27
|
+
Of course, even a well-written book doesn't always mean a good movie. I have
|
28
|
+
seen some movies apparently based on his works that made me think: As an
|
29
|
+
author, he must be crying and hiding his face... all the way to the bank.
|
30
|
+
|
31
|
+
And though I have seen more King movies than I have read King novels, I
|
32
|
+
thought I could see his work shining through here. (Pun totally not intended.)
|
33
|
+
Add to that a few wonderful and innovative bits of CG, some interesting
|
34
|
+
camera angles, and yes, some really decent acting here and there. What you
|
35
|
+
then get is not exactly a masterpiece, but something well worth watching.
|
36
|
+
|
37
|
+
There are arguably some downsides here. Some of the effects might be a little
|
38
|
+
cheesy, some of the tropes a little timeworn, some of the acting a little off.
|
39
|
+
But so what? It's better than 90% of the stuff I've streamed lately.
|
40
|
+
|
41
|
+
I don't like "stars" for reviews. I'm trying to figure out what other kind of
|
42
|
+
little icon or widget or thingy I can use. But until then: <i>Doctor Sleep</i>
|
43
|
+
gets five stars.
|
data/doc/old-repo
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
/Users/Hal/.blogs/
|
@@ -0,0 +1,8 @@
|
|
1
|
+
{
|
2
|
+
"client_id": "YOUR_CLIENT_ID_HERE",
|
3
|
+
"client_secret": "YOUR_CLIENT_SECRET_HERE",
|
4
|
+
"username": "YOUR_REDDIT_USERNAME",
|
5
|
+
"password": "YOUR_REDDIT_PASSWORD",
|
6
|
+
"user_agent": "scriptorium:autopost:v1.0 (by /u/YOUR_USERNAME)",
|
7
|
+
"default_subreddit": "YOUR_DEFAULT_SUBREDDIT"
|
8
|
+
}
|
@@ -0,0 +1,207 @@
|
|
1
|
+
# Reddit Integration for Scriptorium
|
2
|
+
|
3
|
+
Scriptorium includes a Reddit autoposting feature that allows you to automatically submit blog posts to Reddit when they are published.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
The Reddit integration uses a Ruby-to-Python bridge approach:
|
8
|
+
- **Ruby side**: Handles Scriptorium integration and data preparation
|
9
|
+
- **Python side**: Uses PRAW (Python Reddit API Wrapper) for actual Reddit API calls
|
10
|
+
|
11
|
+
This approach leverages the mature and well-tested PRAW library while keeping the integration clean and maintainable.
|
12
|
+
|
13
|
+
## Setup
|
14
|
+
|
15
|
+
### 1. Install Python Dependencies
|
16
|
+
|
17
|
+
**Recommended: Use a Virtual Environment**
|
18
|
+
```bash
|
19
|
+
# Create a virtual environment for Scriptorium
|
20
|
+
python3 -m venv ~/.scriptorium-python
|
21
|
+
|
22
|
+
# Activate the virtual environment
|
23
|
+
source ~/.scriptorium-python/bin/activate
|
24
|
+
|
25
|
+
# Install PRAW
|
26
|
+
pip install praw
|
27
|
+
```
|
28
|
+
|
29
|
+
**Alternative: Install with --user flag**
|
30
|
+
```bash
|
31
|
+
pip3 install --user praw
|
32
|
+
```
|
33
|
+
|
34
|
+
**Note**: Modern Python installations on macOS may require using a virtual environment or the `--user` flag to avoid "externally-managed-environment" errors.
|
35
|
+
|
36
|
+
### 2. Create Reddit App
|
37
|
+
|
38
|
+
1. Go to [Reddit App Preferences](https://www.reddit.com/prefs/apps)
|
39
|
+
2. Click "create another app"
|
40
|
+
3. Set type to "script"
|
41
|
+
4. Note your credentials:
|
42
|
+
- `client_id` (the string under your app name)
|
43
|
+
- `client_secret` (the "secret" field)
|
44
|
+
- `username` (your Reddit username)
|
45
|
+
- `password` (your Reddit password)
|
46
|
+
|
47
|
+
### 3. Configure Credentials
|
48
|
+
|
49
|
+
Create a `reddit_credentials.json` file in your Scriptorium config directory:
|
50
|
+
|
51
|
+
```json
|
52
|
+
{
|
53
|
+
"client_id": "YOUR_CLIENT_ID_HERE",
|
54
|
+
"client_secret": "YOUR_CLIENT_SECRET_HERE",
|
55
|
+
"username": "YOUR_REDDIT_USERNAME",
|
56
|
+
"password": "YOUR_REDDIT_PASSWORD",
|
57
|
+
"user_agent": "scriptorium:autopost:v1.0 (by /u/YOUR_USERNAME)",
|
58
|
+
"default_subreddit": "YOUR_DEFAULT_SUBREDDIT"
|
59
|
+
}
|
60
|
+
```
|
61
|
+
|
62
|
+
**Security Note**: Keep this file secure and never commit it to version control.
|
63
|
+
|
64
|
+
## Usage
|
65
|
+
|
66
|
+
### Basic Autoposting
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
# In your Scriptorium code
|
70
|
+
post_data = {
|
71
|
+
title: "My Blog Post Title",
|
72
|
+
url: "https://myblog.com/posts/my-post.html",
|
73
|
+
content: "Post content or excerpt",
|
74
|
+
subreddit: "programming" # Optional, uses default if not specified
|
75
|
+
}
|
76
|
+
|
77
|
+
# Autopost to Reddit
|
78
|
+
success = repo.autopost_to_reddit(post_data)
|
79
|
+
```
|
80
|
+
|
81
|
+
### Check Configuration
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
# Check if Reddit integration is configured
|
85
|
+
if repo.reddit_configured?
|
86
|
+
puts "Reddit integration is ready"
|
87
|
+
else
|
88
|
+
puts "Reddit integration not configured"
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
### Get Reddit Configuration
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
# Access Reddit configuration
|
96
|
+
config = repo.reddit.config
|
97
|
+
puts "Using Reddit account: #{config['username']}"
|
98
|
+
```
|
99
|
+
|
100
|
+
## API Reference
|
101
|
+
|
102
|
+
### Scriptorium::Reddit
|
103
|
+
|
104
|
+
#### `new(repo)`
|
105
|
+
Creates a new Reddit integration instance.
|
106
|
+
|
107
|
+
#### `autopost(post_data, subreddit = nil)`
|
108
|
+
Autoposts content to Reddit.
|
109
|
+
|
110
|
+
**Parameters:**
|
111
|
+
- `post_data` (Hash): Post information
|
112
|
+
- `title` (String): Post title (required)
|
113
|
+
- `url` (String): Post URL (required)
|
114
|
+
- `content` (String): Post content or excerpt
|
115
|
+
- `subreddit` (String): Target subreddit
|
116
|
+
- `subreddit` (String): Override subreddit (optional)
|
117
|
+
|
118
|
+
**Returns:** `true` on success, `false` on failure
|
119
|
+
|
120
|
+
#### `configured?`
|
121
|
+
Checks if Reddit integration is properly configured.
|
122
|
+
|
123
|
+
**Returns:** `true` if credentials and Python script exist
|
124
|
+
|
125
|
+
#### `config`
|
126
|
+
Gets the parsed Reddit configuration.
|
127
|
+
|
128
|
+
**Returns:** Hash with credentials or `nil` if not configured
|
129
|
+
|
130
|
+
### Scriptorium::Repo
|
131
|
+
|
132
|
+
#### `reddit`
|
133
|
+
Gets the Reddit integration instance (lazy-loaded).
|
134
|
+
|
135
|
+
#### `autopost_to_reddit(post_data, subreddit = nil)`
|
136
|
+
Convenience method for autoposting.
|
137
|
+
|
138
|
+
#### `reddit_configured?`
|
139
|
+
Convenience method to check Reddit configuration.
|
140
|
+
|
141
|
+
## Error Handling
|
142
|
+
|
143
|
+
The integration includes comprehensive error handling:
|
144
|
+
|
145
|
+
- **Missing credentials**: Raises `FileNotFoundError` exception
|
146
|
+
- **Missing Python script**: Raises `FileNotFoundError` exception
|
147
|
+
- **Invalid JSON**: Returns `nil` for config, logs error
|
148
|
+
- **API failures**: Returns `false`, logs error details
|
149
|
+
- **Temporary file cleanup**: Automatic cleanup in all cases
|
150
|
+
|
151
|
+
## Testing
|
152
|
+
|
153
|
+
Run the Reddit integration tests:
|
154
|
+
|
155
|
+
```bash
|
156
|
+
ruby test/unit/reddit_test.rb
|
157
|
+
```
|
158
|
+
|
159
|
+
The tests cover:
|
160
|
+
- Initialization and configuration
|
161
|
+
- Credentials management
|
162
|
+
- Error handling
|
163
|
+
- Temporary file cleanup
|
164
|
+
- Integration with Repo class
|
165
|
+
|
166
|
+
## Security Considerations
|
167
|
+
|
168
|
+
1. **Credentials Storage**: Store credentials securely and never commit to version control
|
169
|
+
2. **User Agent**: Use a descriptive user agent string as required by Reddit
|
170
|
+
3. **Rate Limiting**: PRAW handles Reddit's rate limiting automatically
|
171
|
+
4. **Permissions**: Only request necessary permissions for your app
|
172
|
+
|
173
|
+
## Troubleshooting
|
174
|
+
|
175
|
+
### Common Issues
|
176
|
+
|
177
|
+
1. **"Reddit credentials file not found"**
|
178
|
+
- Ensure `reddit_credentials.json` exists in your config directory
|
179
|
+
- Check file permissions
|
180
|
+
|
181
|
+
2. **"Reddit autopost Python script not found"**
|
182
|
+
- Ensure `scripts/reddit_autopost.py` exists
|
183
|
+
- Check that Python 3 is installed
|
184
|
+
|
185
|
+
3. **Authentication failures**
|
186
|
+
- Verify your Reddit credentials are correct
|
187
|
+
- Check that your Reddit app is properly configured
|
188
|
+
- Ensure your Reddit account has the necessary permissions
|
189
|
+
|
190
|
+
4. **Subreddit posting failures**
|
191
|
+
- Verify the subreddit exists and is accessible
|
192
|
+
- Check subreddit posting rules and restrictions
|
193
|
+
- Ensure your account meets subreddit posting requirements
|
194
|
+
|
195
|
+
### Debug Mode
|
196
|
+
|
197
|
+
Enable debug logging by setting the log level in your Scriptorium configuration.
|
198
|
+
|
199
|
+
## Future Enhancements
|
200
|
+
|
201
|
+
Potential improvements for the Reddit integration:
|
202
|
+
|
203
|
+
1. **Comment posting**: Support for posting comments on submissions
|
204
|
+
2. **Crossposting**: Support for crossposting to multiple subreddits
|
205
|
+
3. **Scheduling**: Delayed posting capabilities
|
206
|
+
4. **Analytics**: Track post performance and engagement
|
207
|
+
5. **Moderation**: Pre-posting content validation and filtering
|
data/doc/user.lt3
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
Intro and overview
|
2
|
+
- Static files
|
3
|
+
- Stored locally, deployed remotely
|
4
|
+
- One repository, many views
|
5
|
+
- terminology
|
6
|
+
- Livetext support
|
7
|
+
- markdown?
|
8
|
+
|
9
|
+
Getting started (5-minute blog)
|
10
|
+
|
11
|
+
The UI(s)
|
12
|
+
- Views
|
13
|
+
- listing
|
14
|
+
- add a view
|
15
|
+
- edit view settings
|
16
|
+
- create a post
|
17
|
+
- preview
|
18
|
+
- deploy
|
19
|
+
- live browsing
|
20
|
+
- Posts
|
21
|
+
- List drafts/posts
|
22
|
+
- Create/finish draft
|
23
|
+
- Edit
|
24
|
+
- Delete/undelete
|
25
|
+
- Livetext in brief
|
26
|
+
- Themes
|
27
|
+
- the standard theme
|
28
|
+
- clone and edit
|
29
|
+
- Widgets
|
30
|
+
- Links
|
31
|
+
- Pages
|
32
|
+
- Featured posts
|
33
|
+
|
34
|
+
Livetext in more detail
|
35
|
+
|