cliptic 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +25 -0
- data/LICENSE.txt +21 -0
- data/README.md +195 -0
- data/Rakefile +4 -0
- data/bin/cliptic +5 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/cliptic.gemspec +25 -0
- data/lib/cliptic.rb +53 -0
- data/lib/cliptic/config.rb +99 -0
- data/lib/cliptic/database.rb +247 -0
- data/lib/cliptic/interface.rb +270 -0
- data/lib/cliptic/lib.rb +64 -0
- data/lib/cliptic/main.rb +839 -0
- data/lib/cliptic/menus.rb +135 -0
- data/lib/cliptic/terminal.rb +72 -0
- data/lib/cliptic/version.rb +5 -0
- data/lib/cliptic/windows.rb +197 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ee1235c23dbbbddeee63cc9ff70d7042bdb3384a4e350e801137641db2d5470a
|
4
|
+
data.tar.gz: e9703a205b9c334034d776138c299fa844e31852842ec6200d6c7618b48c885b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a7308fd566cea0d68c23c00a10e61fad9b18a091d3c733387417c8ded1c4dd22abc53e1a7381e9c8b205f353b58cf761e7e27bd762b24d8fa5d72964b5e12ba0
|
7
|
+
data.tar.gz: ede96821bb377c53524b5ecdc2df06552807bee236d22cf281bdb04d95ef75910f6749a5f3aa21ffaf0680b03fe2bc930e44ed4c82e89642a636331f40277db9
|
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
cliptic (0.1.0)
|
5
|
+
curb
|
6
|
+
curses
|
7
|
+
sqlite3
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
curb (0.9.11)
|
13
|
+
curses (1.4.0)
|
14
|
+
rake (13.0.3)
|
15
|
+
sqlite3 (1.4.2)
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
x86_64-darwin-18
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
cliptic!
|
22
|
+
rake (~> 13.0)
|
23
|
+
|
24
|
+
BUNDLED WITH
|
25
|
+
2.2.15
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2021 Christian Welham
|
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
|
13
|
+
all 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
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,195 @@
|
|
1
|
+
# CLIptic
|
2
|
+
|
3
|
+
![](https://github.com/apexatoll/cliptic-files/blob/master/demo.gif)
|
4
|
+
|
5
|
+
- A command-line interface for downloading and playing cryptic crosswords from within the terminal.
|
6
|
+
- Puzzles are sourced from the free crosswords uploaded daily to [Lovatt's][1].
|
7
|
+
- CLIptic is written in Ruby using the ncurses library
|
8
|
+
|
9
|
+
## Features
|
10
|
+
- VIM-like keybindings
|
11
|
+
- Puzzles scraped daily from Lovatt's. Puzzles are cached locally to prevent excessive requests
|
12
|
+
- Progress can be saved to continue puzzles at a later time
|
13
|
+
- Time taken to complete the puzzle is logged on completion of puzzle. High scores can be viewed within CLIptic
|
14
|
+
- Track progress for puzzles released in the last week
|
15
|
+
- Puzzle history is tracked, making it easy to pick up recently played puzzles
|
16
|
+
- Select puzzles to play by date manually (puzzles are available for up to 9 months from release)
|
17
|
+
- Customisation of CLIptic's appearance
|
18
|
+
|
19
|
+
## Dependencies
|
20
|
+
|
21
|
+
### System
|
22
|
+
- Ruby
|
23
|
+
- Ncurses
|
24
|
+
- Curl
|
25
|
+
|
26
|
+
### Gems
|
27
|
+
- curb
|
28
|
+
- curses
|
29
|
+
- sqlite3
|
30
|
+
|
31
|
+
## Installing
|
32
|
+
|
33
|
+
### As a Gem
|
34
|
+
- CLIptic is available as a Ruby Gem. To install, simply run:
|
35
|
+
```bash
|
36
|
+
gem install cliptic
|
37
|
+
```
|
38
|
+
### Manually
|
39
|
+
- Or, to install manually:
|
40
|
+
```bash
|
41
|
+
git clone https://github.com/apexatoll/cliptic
|
42
|
+
cd cliptic
|
43
|
+
rake build install
|
44
|
+
```
|
45
|
+
|
46
|
+
## Running
|
47
|
+
- To run cliptic after installation, simply run the command `cliptic` from within the terminal
|
48
|
+
- When the program is first run it will ask the user whether they want cliptic to generate a default config file. This is located in `~/.config/cliptic/cliptic.rc`
|
49
|
+
- If the screen is too small to display cliptic, please resize until the prompt disappears
|
50
|
+
|
51
|
+
### Other Commands
|
52
|
+
- There are other commands that can be run from the command line
|
53
|
+
|
54
|
+
#### Today
|
55
|
+
- The command `cliptic today` will play today's puzzle
|
56
|
+
- This command can be followed with a negative number to play a puzzle n days before today
|
57
|
+
- For example `cliptic today -2` will play the puzzle from the day before yesterday
|
58
|
+
|
59
|
+
#### Resetting Progress
|
60
|
+
- The command `cliptic reset` will allow the user to reset progress in cliptic.
|
61
|
+
- The command can be followed with either `all`, `states`, `scores` or `recents`
|
62
|
+
- `all` resets all progress
|
63
|
+
- `states` resets all game progress
|
64
|
+
- `scores` resets high scores
|
65
|
+
- `recents` resets puzzle history
|
66
|
+
|
67
|
+
## Main Menu
|
68
|
+
- On the main menu there are several options
|
69
|
+
* Play today's puzzle
|
70
|
+
* Show this week's progress
|
71
|
+
* Select a date manually
|
72
|
+
* Display recent puzzles
|
73
|
+
* Show high scores
|
74
|
+
* Exit cliptic
|
75
|
+
|
76
|
+
### Menu Navigation
|
77
|
+
| Command | Action |
|
78
|
+
|------------------|----------------|
|
79
|
+
| `j/DOWN`, `k/UP` | Move cursor |
|
80
|
+
| `q` | Back/quit |
|
81
|
+
| `ENTER` | Make selection |
|
82
|
+
|
83
|
+
## Solving Puzzles
|
84
|
+
- By default, cliptic uses vim-like keybindings for navigation and text manipulation. There are plans to release more "accessible" keybindings in the future.
|
85
|
+
- Text manipulation is modal akin to vim. Vim-users will be familiar with insert and normal modes
|
86
|
+
- The currently focussed clue is displayed within the window at the bottom of the screen. If you are on a cell that is an intersection of two clues (ie an across and a down) you can swap between them using `TAB`
|
87
|
+
|
88
|
+
### Game Modes
|
89
|
+
- There are 2 game modes that can be played. These can be changed in the cliptic config file.
|
90
|
+
1. *Auto_mark* = 1 (default)
|
91
|
+
- Each clue is marked once every cell is filled
|
92
|
+
- The clue will be highlighted green or red depending on whether the attempt is correct
|
93
|
+
2. *Auto_mark* = 0
|
94
|
+
- No clues are marked automatically, similar to a paper crossword
|
95
|
+
- Clues can be checked manually using the `^G` command
|
96
|
+
|
97
|
+
### Global Commands
|
98
|
+
|
99
|
+
| Command | Action |
|
100
|
+
|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
101
|
+
| `^S` | Save current progress (note that progress is saved when exiting puzzles by default) |
|
102
|
+
| `^R` | Reveals solution for focussed clue (note that this forfeits adding this puzzle to high scores) |
|
103
|
+
| `^C` | Exit puzzle |
|
104
|
+
| `^E` | Resets timer and progress for puzzle |
|
105
|
+
| `^G` | Mark current progress (only relevant if auto_mark is set to 0) |
|
106
|
+
| `^P` | Pause game |
|
107
|
+
|
108
|
+
### Navigation (Normal Mode)
|
109
|
+
- There are several ways to navigate the cells of the cliptic grid in **NORMAL MODE**.
|
110
|
+
|
111
|
+
| Command | Action |
|
112
|
+
|--------------------|----------------------------------------------------------------------------------------------------------------------------------|
|
113
|
+
| `h`, `j`, `k`, `l` | Move cursor left, up, down, right. Arrow keys can also be used |
|
114
|
+
| `(n)w` | Move to (nth) next unsolved clue |
|
115
|
+
| `(n)b` | Move to (nth) previous unsolved clue |
|
116
|
+
| `e` | Move to end of clue |
|
117
|
+
| `<clue number>g` | Move to clue by number |
|
118
|
+
| `<cell number>G` | Move to cell by number (not 0 indexed |
|
119
|
+
| `TAB` | Swap from across to down clue (or vice versa) |
|
120
|
+
|
121
|
+
### Entering Text (Insert Mode)
|
122
|
+
|
123
|
+
| Command | Action |
|
124
|
+
|-------------|-------------------------------------|
|
125
|
+
| `a-z` | Enter character to cell |
|
126
|
+
| `BACKSPACE` | Delete one character |
|
127
|
+
| `ESC` | Exit insert mode. Enter normal mode |
|
128
|
+
|
129
|
+
### Normal Mode
|
130
|
+
|
131
|
+
| Command | Action |
|
132
|
+
|-----------|-----------------------------------------------------------------------------------------|
|
133
|
+
| `I` | Move to the start of the clue and enter insert mode |
|
134
|
+
| `a` | Advance one cell and enter insert mode |
|
135
|
+
| `c(obj)` | calls d(obj) then enters insert mode |
|
136
|
+
| `d(obj)` | delete the object provided after d (may be w for word or l for character) |
|
137
|
+
| `i` | Enter insert mode |
|
138
|
+
| `r(char)` | Replaces the character under the cursor with `char` |
|
139
|
+
| `x` | deletes the character under the cursor |
|
140
|
+
|
141
|
+
## Configuration
|
142
|
+
- Cliptic settings can be added to the cliptic.rc file found at `~/.config/cliptic/cliptic.rc`
|
143
|
+
|
144
|
+
### Interface
|
145
|
+
- Affect how cliptic functions
|
146
|
+
- Set using the format
|
147
|
+
```
|
148
|
+
set <setting> <0/1>
|
149
|
+
```
|
150
|
+
|
151
|
+
#### Settable Items
|
152
|
+
|
153
|
+
| Item | Description | Default |
|
154
|
+
|--------------|--------------------------------|---------|
|
155
|
+
| auto_advance | Move to next clue after solve | 1 |
|
156
|
+
| auto_mark | Mark clues as they are entered | 1 |
|
157
|
+
| auto_save | Save progress on exit | 1 |
|
158
|
+
|
159
|
+
### Colours
|
160
|
+
- Colours are numbered 1-16.
|
161
|
+
* 0 is default terminal color
|
162
|
+
* 1-8 equates to your terminals 8 default colours.
|
163
|
+
* 9-16 equate to same colours as the background and blank as the foreground
|
164
|
+
- To set colour settings use the format
|
165
|
+
```
|
166
|
+
hi <obj> <colour>
|
167
|
+
```
|
168
|
+
|
169
|
+
#### Settable Items
|
170
|
+
|
171
|
+
| Item | Description | Default |
|
172
|
+
|------------|----------------------------|---------|
|
173
|
+
| active_num | Grid number of active clue | 3 |
|
174
|
+
| bar | Top and bottom bars | 16 |
|
175
|
+
| block | Grid blocks | 8 |
|
176
|
+
| box | Box outlines | 8 |
|
177
|
+
| grid | cliptic grids | 8 |
|
178
|
+
| incorrect | Incorrect clue attempt | 1 |
|
179
|
+
| correct | Correct clue attempt | 2 |
|
180
|
+
| prompt | Menu prompt | 3 |
|
181
|
+
| default | Default text color | 0 |
|
182
|
+
| meta | Clue box metadata | 3 |
|
183
|
+
| num | Inactive grid numbers | 8 |
|
184
|
+
| logo_text | Logo text color | 3 |
|
185
|
+
| I | Insert mode prompt | 15 |
|
186
|
+
| N | Normal mode prompt | 12 |
|
187
|
+
|
188
|
+
## Feedback
|
189
|
+
- Cliptic is still in development
|
190
|
+
- If you have any feature requests or find any bugs please leave a new issue
|
191
|
+
- Contributions welcome!
|
192
|
+
|
193
|
+
*Dedicated to WES who passed on to me his love of crosswords*
|
194
|
+
|
195
|
+
[1]: https://lovattspuzzles.com/online-puzzles-competitions/daily-cryptic-crossword/
|
data/Rakefile
ADDED
data/bin/cliptic
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "cliptic"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/cliptic.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative "lib/cliptic/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "cliptic"
|
5
|
+
spec.version = Cliptic::VERSION
|
6
|
+
spec.authors = ["Christian Welham"]
|
7
|
+
spec.email = ["welhamm@gmail.com"]
|
8
|
+
spec.summary = "Terminal-based cryptic crossword player"
|
9
|
+
spec.description = "A terminal user interface to fetch and play cryptic crosswords"
|
10
|
+
spec.homepage = "https://github.com/apexatoll/cliptic"
|
11
|
+
spec.license = "MIT"
|
12
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
13
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
14
|
+
spec.metadata["source_code_uri"] = "https://github.com/apexatoll/cliptic"
|
15
|
+
spec.metadata["changelog_uri"] = "https://github.com/apexatoll/cliptic/CHANGELOG.md"
|
16
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
17
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
18
|
+
end
|
19
|
+
spec.bindir = "bin"
|
20
|
+
spec.executables << "cliptic"
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
spec.add_dependency("curses", "~> 1.4.0")
|
23
|
+
spec.add_dependency("curb", "~> 0.9.11")
|
24
|
+
spec.add_dependency("sqlite3", "~> 1.4.2")
|
25
|
+
end
|
data/lib/cliptic.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
module Cliptic
|
2
|
+
require 'cgi'
|
3
|
+
require 'curb'
|
4
|
+
require 'curses'
|
5
|
+
require 'date'
|
6
|
+
require 'fileutils'
|
7
|
+
require 'json'
|
8
|
+
require 'sqlite3'
|
9
|
+
require 'time'
|
10
|
+
class Screen
|
11
|
+
extend Curses
|
12
|
+
def self.setup
|
13
|
+
init_curses
|
14
|
+
set_colors if has_colors?
|
15
|
+
redraw
|
16
|
+
end
|
17
|
+
def self.init_curses
|
18
|
+
init_screen
|
19
|
+
raw
|
20
|
+
noecho
|
21
|
+
curs_set(0)
|
22
|
+
end
|
23
|
+
def self.set_colors
|
24
|
+
start_color
|
25
|
+
use_default_colors
|
26
|
+
1.upto(8) do |i|
|
27
|
+
init_pair(i, i, -1)
|
28
|
+
init_pair(i+8, 0, i)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
def self.clear
|
32
|
+
stdscr.clear
|
33
|
+
stdscr.refresh
|
34
|
+
end
|
35
|
+
def self.too_small?
|
36
|
+
lines < 36 || cols < 61
|
37
|
+
end
|
38
|
+
def self.redraw(cb:nil)
|
39
|
+
Interface::Resizer.new.show if Screen.too_small?
|
40
|
+
Screen.clear
|
41
|
+
cb.call if cb
|
42
|
+
end
|
43
|
+
end
|
44
|
+
require_relative "cliptic/version"
|
45
|
+
require_relative "cliptic/terminal.rb"
|
46
|
+
require_relative "cliptic/lib.rb"
|
47
|
+
require_relative "cliptic/config.rb"
|
48
|
+
require_relative "cliptic/database.rb"
|
49
|
+
require_relative "cliptic/windows.rb"
|
50
|
+
require_relative "cliptic/interface.rb"
|
51
|
+
require_relative "cliptic/menus.rb"
|
52
|
+
require_relative "cliptic/main.rb"
|
53
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Cliptic
|
2
|
+
module Config
|
3
|
+
Dir_Path = "#{Dir.home}/.config/cliptic"
|
4
|
+
File_Path = "#{Dir_Path}/cliptic.rc"
|
5
|
+
class Default
|
6
|
+
def self.colors
|
7
|
+
{
|
8
|
+
box:8, grid:8, bar:16, logo_grid:8,
|
9
|
+
logo_text:1, title:3, stats:2, active_num:3,
|
10
|
+
num:8, block:8, I:15, N:12, correct:2,
|
11
|
+
incorrect:1, meta:3, cluebox:8
|
12
|
+
}
|
13
|
+
end
|
14
|
+
def self.config
|
15
|
+
{
|
16
|
+
auto_advance:1,
|
17
|
+
auto_mark:1,
|
18
|
+
auto_save:1
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
class Setter
|
23
|
+
attr_reader :colors, :config
|
24
|
+
def initialize
|
25
|
+
$colors = Default.colors
|
26
|
+
$config = Default.config
|
27
|
+
end
|
28
|
+
def set
|
29
|
+
cfg_file_exists? ?
|
30
|
+
read_cfg : gen_cfg_menu.choose_opt
|
31
|
+
$config = make_bool($config)
|
32
|
+
end
|
33
|
+
private
|
34
|
+
def read_cfg
|
35
|
+
Reader.new.tap do |file|
|
36
|
+
cfg_file_keys.each do |dest, key|
|
37
|
+
dest.merge!(file.read(**key))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
def cfg_file_keys
|
42
|
+
{
|
43
|
+
$colors => {key:"hi"},
|
44
|
+
$config => {key:"set"}
|
45
|
+
}
|
46
|
+
end
|
47
|
+
def cfg_file_exists?
|
48
|
+
File.exist?(File_Path)
|
49
|
+
end
|
50
|
+
def make_bool(hash)
|
51
|
+
hash.map{|k, v| [k, v == 1]}.to_h
|
52
|
+
end
|
53
|
+
def gen_cfg_menu
|
54
|
+
Cliptic::Interface::Yes_No_Menu.new(
|
55
|
+
yes:->{Generator.new.write},
|
56
|
+
title:"Generate a config file?"
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
class Reader
|
61
|
+
attr_reader :lines
|
62
|
+
def initialize
|
63
|
+
@lines = File.read(File_Path).each_line.map.to_a
|
64
|
+
end
|
65
|
+
def read(key:)
|
66
|
+
lines.grep(/^\s*#{key}/)
|
67
|
+
.map{|l| l.gsub(/^\s*#{key}\s+/, "")
|
68
|
+
.split(/\s+/)}
|
69
|
+
.map{|k, v| [k.to_sym, v.to_i]}
|
70
|
+
.to_h
|
71
|
+
end
|
72
|
+
end
|
73
|
+
class Generator
|
74
|
+
def write
|
75
|
+
FileUtils.mkdir_p(Dir_Path) unless cfg_dir_exists
|
76
|
+
File.write(File_Path, make_file)
|
77
|
+
end
|
78
|
+
private
|
79
|
+
def cfg_dir_exists
|
80
|
+
Dir.exist?(Dir_Path)
|
81
|
+
end
|
82
|
+
def file_data
|
83
|
+
{
|
84
|
+
"Colour Settings" => {
|
85
|
+
cmd:"hi", values:Default.colors
|
86
|
+
},
|
87
|
+
"Interface Settings" => {
|
88
|
+
cmd:"set", values:Default.config
|
89
|
+
}
|
90
|
+
}
|
91
|
+
end
|
92
|
+
def make_file
|
93
|
+
file_data.map do |comment, data|
|
94
|
+
["//#{comment}"] + data[:values].map{|k, v| "#{data[:cmd]} #{k} #{v}"} + ["\n"]
|
95
|
+
end.join("\n")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|