├── History.md
├── Makefile
├── Readme.md
├── black-Linen.png
├── bm
├── licenses.txt
└── scripts
├── bmflyounet_to_bm060.sh
└── bmtj_to_bm060.sh
/History.md:
--------------------------------------------------------------------------------
1 |
2 | 0.6.5 / 2016-03-xx
3 | ==================
4 |
5 | * In some case, the sed operation to grab the title is not working. For those who have `hxselect` installed, it should always work.
6 | * With `-E` the bm.lnk file is open with your $EDITOR (default is vi).
7 | * With `-q` bm looks for the Title of the web page.
8 | * Fix : When grabing the picture with `-P` bm used the md5 instead of the URL.
9 |
10 | 0.6.4 / 2016-03-22
11 | ==================
12 |
13 | * Fix : When searching for a tag and Title contains |. Results were incorrect.
14 |
15 | 0.6.3 / 2016-03-11
16 | ==================
17 |
18 | * Fix #20 : Issue with tags when a Title contains a comma. Stats are weird.
19 |
20 | 0.6.2 / 2016-03-08
21 | ==================
22 |
23 | * Changing the curl call. Now follow links (eg. the 301 code).
24 | * Fix #18 : Issue with BM on Apple (related to readlink binary).
25 |
26 | 0.6.1 / 2016-02-23
27 | ==================
28 |
29 | * Adding permissive licenses :
30 | * - WTFPL : do What The Fuck you Want to Public License
31 | * - DSSL : Demerden Sie Sich License
32 |
33 | 0.6.0 / 2016-02-21
34 | ==================
35 |
36 | * Fields order is now modified. Date is now the second field instead of last.
37 | * 2 scripts are present to migrate from tj/bm and fromo Flyounet/bm to the v0.6.0.
38 | * Fix #17 : Add a Flag (-r) to open image stored for a link.
39 | * Fix #18 : Store a date for the screenshot taken.
40 | * Fix #19 : Add a Flag (-P) to take the screenshot for a specific link.
41 | * Updated the function related to statistic to also include config info and orphaned pictures.
42 | * Added 2 Flags -n (-N) to sort results by date (reverse)
43 |
44 | 0.5.3 / 2016-02-16
45 | ==================
46 |
47 | * Documentation update
48 | * History update
49 |
50 | 0.5.2 / 2016-02-11
51 | ==================
52 |
53 | * Fix #15 : Title with Pipe not working (and also correct the delete function due to this correction)
54 | * Fix #16 : Autoincrement doesn't work for more than 9 item
55 |
56 | 0.5.1 / 2016-02-02
57 | ==================
58 |
59 | * Added an alternate print list with `-z`
60 | * HTML file generated should be good in validators
61 |
62 | 0.5.0 / 2016-02-01
63 | ==================
64 |
65 | * Engine rewritted
66 | * Added tons of configuration variables
67 | * Added use of `cutycapt` for Linux
68 | * Added duplicate check
69 | * Added Accelerator to find your bookmark
70 | * Changed interface, the old one still exist but new functions use arguments `-a`, `-t`, ...
71 | * Generate screenshot when added in bookmark
72 | * Added backup
73 | * And more, see source or help.
74 |
75 | 0.4.0 / 2012-03-30
76 | ==================
77 |
78 | * Added new HTML style
79 |
80 | 0.3.0 / 2012-03-15
81 | ==================
82 |
83 | * Added: use webkit2png for thumbs. Closes #2
84 |
85 | 0.2.0 / 2012-03-15
86 | ==================
87 |
88 | * Added nicer display for large urls
89 | * Added: strip http:// when listing
90 |
91 | 0.1.0 / 2012-03-15
92 | ==================
93 |
94 | * Added experimental screenshots feature
95 |
96 | 0.0.1 / 2012-03-15
97 | ==================
98 |
99 | - Initial release
100 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | PREFIX=/usr/local
3 |
4 | install:
5 | cp -f bm $(PREFIX)/bin/bm
6 | if [ ! -d "/usr/share/bm" ]; then mkdir -p "/usr/share/bm"; fi
7 | cp -f "black-Linen.png" "/usr/share/bm/black-Linen.png"
8 | cp -f Makefile "/usr/share/bm/Makefile"
9 |
10 | uninstall:
11 | rm -f $(PREFIX)/bin/bm
12 | rm -f "/usr/share/bm/black-Linen.png"
13 | rm -f "/usr/share/bm/Makefile"
14 | rmdir "/usr/share/bm"
15 |
16 | .PHONY: install uninstall
17 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 |
2 | ## BM
3 |
4 | Simple bash CLI bookmarks.
5 |
6 | Firstly designed for Mac and now also for Linux, supports search on criteria,
7 | accelerator, tags, Screenshots, configuration file, backup, and also
8 | generate a HTML file with bookmarks and Screenshots.
9 |
10 | **/!\ : version prior to v0.6.6 had a bug when deleting. Don't use the delete function or update !**
11 | If you upgrade from a version prior to v0.6.0, read at the end.
12 |
13 | 
14 |
15 | Please note, BM needs some binaries to work see configuration to change them):
16 |
17 | * For the Screenshot part:
18 | * - `cutycapt` for Linux
19 | * - `webkit2png` for Mac.
20 | * For the clipboard copy:
21 | * - `xsel` for Linux
22 | * - As I don't have any Mac, nothing for the time being.
23 | * For the md5 part:
24 | * - `md5sum` for Linux
25 | * - `md5` for Mac.
26 | * Other tools: `sed`, `awk`, `date`, `iconv`, `cat`, `curl`, `column` and `bash`
27 |
28 | ## Install
29 |
30 | ```
31 | $ make install
32 | $ make uninstall
33 | ```
34 |
35 | ## Example
36 |
37 | Add a bookmark:
38 |
39 | $ bm add http://subtlepatterns.com "tiling background images" design textures
40 |
41 | Open it later:
42 |
43 | $ bm subtle
44 |
45 | Search for design related bookmarks:
46 |
47 | 
48 |
49 | ## Usage
50 |
51 | ```
52 | Usage: ./bm [modifier(s)] command [option(s)]
53 |
54 | Commands :
55 | ==========
56 | -h Print this help
57 | -H Print help for legacy usage
58 | -v/-V Print the version
59 | -a 'URL' Add the URL to bookmark file
60 | Options for -a
61 | -t "TagList" Tags are sparated by a comma ,
62 | -T "Title" Title for this URL (if empty and allowed Title
63 | downloaded)
64 | -A "accel" Accelerator when search for URLs (start with Accel)
65 | Default is FQDN without gTld (and www, and sheme)
66 | -F Force the bookmark to be created (even if duplicate
67 | or invalid)
68 | -p Force the screenshot to be taken
69 |
70 | -l List all URLs (default action, same thing as calling bm without args)
71 | Options for -l
72 | -z Use the alternate print list
73 | -n Sort the results by date
74 | -N Sort the results by date (reverse)
75 |
76 |
77 | -s 'object' Search for bookmarks
78 | Options for -s
79 | -i Incensitive case search
80 | -z Use the alternate print list
81 | -n Sort the results by date
82 | -N Sort the results by date (reverse)
83 | Objects are
84 | :string Search in accelerator list
85 | +string Search in tags list
86 | =string Search in MD5 list
87 | /string Search in URL list
88 | string Search in full test
89 |
90 | -o 'object' Search for bookmarks and open it (use the same argument as for -s)
91 | Options for -o
92 | -i Incensitive case search
93 | -O If more than one answer force the first bookmark to be open
94 | -Y If more than one answer force ALL bookmarks to be open
95 |
96 | -x 'object' Search for bookmarks and copy it to clipboard (use the same argument as for -s)
97 | Options for -x
98 | -i Incensitive case search
99 | -X If more than one answer force the first bookmark to be copied
100 | -Y If more than one answer force ALL bookmarks to be copied
101 |
102 | -r 'object' Search for bookmarks and Print the recorded associated picture (use the same argument as for -s)
103 | Options for -r
104 | -i Incensitive case search
105 | -O If more than one answer force the first bookmark to have its picture printed
106 | -Y If more than one answer force ALL bookmarks to have their picture printed
107 |
108 | -d 'URL' or Delete the URL from bookmark file
109 | md5sum or
110 | 'URL part' Options for -d
111 | -D Delete first occurence only
112 | -F Force the bookmark to be deleted (even if duplicate)
113 | -p Delete the associated picture (no trash available)
114 |
115 | -g Generate a HTML page with all bookmarks
116 | If used more than once, generate a page per tag
117 | Options for -g
118 | -G "filename" If g==1 then generate then use this filename to generate page
119 | -O Open the file when generated
120 |
121 | -P 'object' Generate all Non existant picture (check done for all URL in bm), if none argument.
122 | If an argument is given (use the same argument as for -s) only the results will have a picture.
123 | Options for -P
124 | -F Force the picture to be taken again (even if already exists).
125 |
126 | -L List all tags
127 |
128 | -C Print the color table (usefull for configuration)
129 |
130 | -S Show statistics about bookmarks/tags (and also configuration)
131 | Options for -S
132 | -p Print the list of orphaned Pictures
133 |
134 | Modifiers :
135 | ===========
136 | -c 'file' Use this configuration file instead of the default one
137 |
138 | -b 'file' Use this bookmark file instead of the default one
139 |
140 | Old Legacy usage still available :
141 | Usage: bm [options] [cmd]
142 |
143 | Commands:
144 |
145 | # add a bookmark with the given url, description, and optional tags
146 | $ bm add [desc] [tag...] [accelerator]
147 |
148 | # open the first bookmark matching
149 | $ bm open
150 | $ bm
151 |
152 | # search the bookmarks via full-text
153 | $ bm search
154 |
155 | # list tags
156 | $ bm tags
157 |
158 | # list bookmarks available
159 | $ bm list
160 | $ bm ls
161 | $ bm
162 |
163 | # display statistics about the bookmarks
164 | $ bm statistics
165 | $ bm stats
166 |
167 | # view bookmark screenshots in your default browser
168 | $ bm view design
169 | $ bm view
170 |
171 | # clear all bookmarks
172 | $ bm clear
173 |
174 | Options:
175 |
176 | -V output bm version
177 | -h output help information for new parameters
178 | -H output this help information
179 | ```
180 |
181 |
182 | ## Screenshots
183 |
184 | Run `bm view [query]` to view the bookmark screenshots in your default browser. This requires `webkit2png(1)` (`brew install webkit2png`).
185 |
186 | ## Storage
187 |
188 | Store the file(s) wherever you want. Use configuration (either internal or with a config file with `-c`), or parameters (`-b` for bookmark file).
189 |
190 | ```
191 | $ cat ~/sync/bm.lnk
192 | bd8b3eff7fa82a0382a3e7576c5363b6|:bm|https://github.com/Flyounet/bm/|bm a cool enhanced bookmark tool for your console|default,shell|2016-01-18T07:21:36Z
193 | 2981b5cae113491ddb18e0d51454f0d9|:bmtj|https://github.com/tj/bm/|The original bm : a cool bookmark tool for your console|default,shell|2016-01-18T07:21:36Z
194 | #fd65acec3e2abff9d2fd3c581df3142d|:7|http://flyounet.net|http-flyounet-net|site,dev, bli,bla,blo,bli|2016-01-20T17:44:02Z
195 | # fd65acec3e2abff9d2fd3c581df3142d|:9|http://flyounet.net|http-flyounet-net|site,dev, ba,bello,belli,bella,arthur,toto,titi,tata,bli,bla,blo,bli|2016-01-20T17:46:24Z
196 | ac313b7d866bc76487858b243f9f3ff0|:HP|http://localhost:631/printers/HP8600|Cups: Imprimante HP 8600|admin,cups,local|2016-01-31T18:33:11Z
197 | ae6461ffeb6cd8393c4c100d026db789|:sync|https://127.0.0.1:8384/|SyncThings Local|admin,network,syncthings|2016-01-31T19:05:08Z
198 | 7ad10b8decf3ef55ce4e8a95e80f4b9d|:home|http://flyounet.net/life|3615 my life|blog,home|2016-01-31T21:09:33Z
199 | 7a3a43da3e8b8f58e5ade40eab35a1fd|:syntaxe|http://flyounet.net/life/2015-11-01-time-to-markdown.html|Syntaxe markdown|blog,home,markdown|2016-01-31T21:12:11Z
200 | ```
201 | Please note the above format is not used anymore since the v0.6.0. The date has been put as the second field of bookmark file.
202 |
203 | If you don't want to see some bookmarks, but want to keep them, you could comment them by adding a hash `#`.
204 |
205 | ## Statistics
206 |
207 | bm provides you some statistics usage
208 |
209 | ```
210 | $ bm -S -p
211 |
212 | ===== Configuration =====
213 | Bookmark file : /home/testuser/bm.lnk
214 | Config file : /home/testuser/bm.conf (but doesn't exist)
215 | Trash file : /home/testuser/.bm.trash
216 | Screenshot directory : /home/testuser/.bm.shots
217 | Backup file(s) : /home/testuser/.bm.lnk.bck*
218 | /home/testuser/.bm.lnk.bck.0
219 | /home/testuser/.bm.lnk.bck.1
220 | /home/testuser/.bm.lnk.bck.2
221 |
222 | ===== Statistics =====
223 | # of Bookmarks : 27
224 | # of Duplicate : 0
225 | # of tags : 26
226 | Top 14 tags used :
227 | admin:8 color:7 bash:7 prompt:6 git:4 design:4 css:4
228 | box:4 system:3 network:3 ecryptfs:3 doc:3 rpi:2 lprab:2
229 | # of Pictures : 34 [# of files in /home/testuser/.bm.shots:39]
230 | All Pictures size : 27M
231 | Bookmark Without Pic : 0
232 | Orphaned pictures : 7
233 |
234 | ===== Orphaned =====
235 | List of orphaned pictures :
236 | - /home/testuser/.bm.shots/16d402a7f1be2304f90ec25924782edc.png [Trashed URL should be: https://github.com/Flyounet/bm]
237 | - /home/testuser/.bm.shots/2981b5cae113491ddb18e0d51454f0d9.png [Trashed URL should be: ]
238 | - /home/testuser/.bm.shots/7a3a43da3e8b8f58e5ade40eab35a1fd.png [Trashed URL should be: Unknown]
239 | - /home/testuser/.bm.shots/7ad10b8decf3ef55ce4e8a95e80f4b9d.png [Trashed URL should be: Unknown]
240 | - /home/testuser/.bm.shots/b88fe41f6aa05370e81bae926da2087c.png [Trashed URL should be: Unknown]
241 | - /home/testuser/.bm.shots/bd8b3eff7fa82a0382a3e7576c5363b6.png [Trashed URL should be: ]
242 | - /home/testuser/.bm.shots/c5c24b5609b0191095197d19d852eb1c.png [Trashed URL should be: http://toto]
243 |
244 | ```
245 |
246 | ## v0.6.0 and above...
247 |
248 | The field's order has been changed. To use the v0.6.0, you have to execute the migration tool located in the `scripts` subdirectory.
249 | It will modify your bookmark file for you (and do a backup first).
250 |
251 | ## Licenses
252 |
253 | * WTFPL : do What The Fuck you Want to Public License
254 | * DSSL : Demerden Sie Sich License
255 |
256 |
--------------------------------------------------------------------------------
/black-Linen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tj/bm/35412a6bc4f7c533ce8d22da1d199380d6fd9b11/black-Linen.png
--------------------------------------------------------------------------------
/bm:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # /*------------------------------------------------------------------------*\
4 | # | |
5 | # | WTFPL & DSSL apply on this material. |
6 | # | |
7 | # +--------------------------------------------------------------------------+
8 | # | |
9 | # | bm : A Bash CLI bookmark manager |
10 | # | Copyright (C) 2012 TJ Holowaychuk — Tous droits réservés. |
11 | # | Copyright (C) 2016 Flyounet — Tous droits réservés. |
12 | # | |
13 | # | Cette œuvre est distribuée SANS AUCUNE GARANTIE hormis celle d'être |
14 | # | distribuée sous les termes de la Licence Demerdez-vous («Demerden Sie |
15 | # | Sich License») telle que publiée par Flyounet : soit la version 1 de |
16 | # | cette licence,soit (à votre gré) toute version ultérieure. |
17 | # | telle que publiée par Flyounet : soit la version 1 de cette licence, |
18 | # | soit (à votre gré) toute version ultérieure. |
19 | # | |
20 | # | Vous devriez avoir reçu une copie de la Licence Démerdez-vous avec cette |
21 | # | œuvre ; si ce n’est pas le cas, consultez : |
22 | # | . |
23 | # | |
24 | # \*------------------------------------------------------------------------*/
25 |
26 |
27 | # default filename for Baker config file (just the filename no path)
28 | readonly _BM_DEFAULT_CONFIG_FILENAME="${_BM_DEFAULT_CONFIG_FILENAME:=bm.conf}"
29 |
30 |
31 | config() {
32 | #echo "Reading Configuration..." >&2
33 | [[ "${__w:=$HOME}" != "${HOME}" ]] && echo "Working dir changed to ${__w}"
34 | [[ "${__w: -1}" != '/' ]] && __w="${__w//\/\//\/}/"
35 | if [ ${__B:=0} -eq 0 ]; then
36 | # If a config file is given, we take it first, or look for a default config file
37 | export _BM_CONFIG_FILE="${__w}${_BM_DEFAULT_CONFIG_FILENAME}"
38 | if [ "$(uname -s)" = 'Linux' -a -f "$(readlink -m "${1:-}" 2>/dev/null)" ]; then
39 | export _BM_CONFIG_FILE="${1}"
40 | . "${1}"
41 | elif [ -e "${1}" ]; then
42 | export _BM_CONFIG_FILE="${1}"
43 | . "${1}"
44 | elif [ ${__n:=0} -eq 0 -a -f "${__w}${_BM_DEFAULT_CONFIG_FILENAME}" ]; then
45 | . "${__w}${_BM_DEFAULT_CONFIG_FILENAME}"
46 | #echo "Default config file loaded ${__w}${_BM_DEFAULT_CONFIG_FILENAME}"
47 | fi
48 | else
49 | export _BM_CONFIG_FILE='none'
50 | fi
51 | # _BM_BOOKMARK_FILE : Where is stored the bookmark file
52 | export _BM_BOOKMARK_FILE="${_BM_BOOKMARK_FILE:=${__w}bm.lnk}"
53 |
54 | # _BM_BOOKMARK_BACKUP_FILE : Where is stored the backup of bookmark file
55 | export _BM_BOOKMARK_BACKUP_FILE="${_BM_BOOKMARK_BACKUP_FILE:=${__w}.bm.lnk.bck}"
56 |
57 | # _BM_HTML_FILE : Location of generated HTML file
58 | export _BM_HTML_FILE="${_BM_HTML_FILE:=${__w}bm.html}"
59 |
60 | # _BM_DELETE_FILE : Where to find the deleted URLs
61 | export _BM_DELETE_FILE="${_BM_DELETE_FILE:=${__w}.bm.trash}"
62 |
63 | # _BM_BOOKMARK_BACKUP : Copy the bookmark file before each modification
64 | export _BM_BOOKMARK_BACKUP=${_BM_BOOKMARK_BACKUP:=true}
65 |
66 | # _BM_BOOKMARK_BACKUP_VERSION : How many copy to keep (0 for 1, 1 for 2, ...)
67 | export _BM_BOOKMARK_BACKUP_VERSION=${_BM_BOOKMARK_BACKUP_VERSION:=2}
68 |
69 | # _BM_DELETE_ALLOWED : Even with the force flag the delete function will not be allowed (true or false)
70 | export _BM_DELETE_ALLOWED=${_BM_DELETE_ALLOWED:=true}
71 |
72 | # _BM_DELETE_TO_FILE : Allow or disallow the deleted URLs to be copied in the Trash (true or false)
73 | export _BM_DELETE_TO_FILE=${_BM_DELETE_TO_FILE:=true}
74 |
75 | # _BM_DELETE_PICTURE : Allow or disallow the picture associated to a URL to be deleted (true or false)
76 | export _BM_DELETE_PICTURE=${_BM_DELETE_PICTURE:=true}
77 |
78 | # _BM_DUPS_DETECT : Look for duplicates URL before insert in bookmark file (ovverided by -F)
79 | export _BM_DUPS_DETECT=${_BM_DUPS_DETECT:=true}
80 |
81 | # _BM_ASK_BEFORE_OPEN : When using bm with a URL (or search term) ask before opening the browser if more than one answer
82 | export _BM_ASK_BEFORE_OPEN=${_BM_ASK_BEFORE_OPEN:=true}
83 |
84 | # _BM_GET_PAGE_TITLE : When adding a URL execute a curl command to get the if none given
85 | export _BM_GET_PAGE_TITLE=${_BM_GET_PAGE_TITLE:=true}
86 |
87 | # _BM_SCREENSHOT_DIRECTORY : Where to store the screenshot taken
88 | export _BM_SCREENSHOT_DIRECTORY="${_BM_SCREENSHOT_DIRECTORY:=${__w}.bm.shots}"
89 |
90 | # _BM_SCREENSHOT_GET : When adding a URL try to take a screenshot in background
91 | export _BM_SCREENSHOT_GET=${_BM_SCREENSHOT_GET:=true}
92 |
93 | # _BM_SCREENSHOT_WAIT : When taking a screenshot wait for the action to finish
94 | export _BM_SCREENSHOT_WAIT=${_BM_SCREENSHOT_WAIT:=false}
95 |
96 | # _BM_OPEN_FIRST : When using open, the first link found is open
97 | # Also work with the copy to clipboard function
98 | export _BM_OPEN_FIRST=${_BM_OPEN_FIRST:=false}
99 |
100 | # _BM_OPEN_ALL : When using open, if more than one result, all are open (with the same function)
101 | # Also work with the copy to clipboard function (overrided by -Y)
102 | export _BM_OPEN_ALL=${_BM_OPEN_ALL:=false}
103 |
104 | # _BM_NO_ARGS_FORCE_HELP : If no args given to script sends to help instead of list all link
105 | export _BM_NO_ARGS_FORCE_HELP=${_BM_NO_ARGS_FORCE_HELP:=false}
106 |
107 | # _BM_CREATE_BOOKMARK_FILE : If bm is called to list and no file exists. bm will create a default one.
108 | export _BM_CREATE_BOOKMARK_FILE=${_BM_CREATE_BOOKMARK_FILE:=true}
109 |
110 | # _BM_CMD_CAPTURE_CHECK : If you don't have tool installed to take screenshot, just put to false.
111 | # It will disable the _BM_GET_SCREENSHOT.
112 | export _BM_CMD_CAPTURE_CHECK=${_BM_CMD_CAPTURE_CHECK:=true}
113 |
114 | # I suppose the uname command is available
115 | # Please note, the PRE & POST capture command will not be analyzes nor verified.
116 | if [ "$(uname -s)" = 'Linux' ]; then
117 | export _BM_CMD_IMAGE_OPEN='feh'
118 | export _BM_CMD_OPEN='xdg-open'
119 | export _BM_CMD_PRE_CAPTURE=''
120 | export _BM_CMD_CAPTURE='cutycapt'
121 | export _BM_CMD_CAPTURE_ARGS='--insecure --url={URL} --out={FILE}'
122 | export _BM_CMD_POST_CAPTURE=''
123 | export _BM_CMD_MD5='md5sum'
124 | export _BM_CMD_COPY='xsel'
125 | else
126 | # To keep commpatibility with the Mac (even i don't have any)
127 | export _BM_CMD_IMAGE_OPEN='open'
128 | export _BM_CMD_OPEN='open'
129 | export _BM_CMD_PRE_CAPTURE=''
130 | export _BM_CMD_CAPTURE='webkit2png'
131 | export _BM_CMD_CAPTURE_ARGS='-C -o {FILE}.png {URL}'
132 | export _BM_CMD_POST_CAPTURE='cp -- "{FILE}-clipped.png" "{FILE}" ; rm -f -- {FILE}-{clipped,full,thumb}.png'
133 | export _BM_CMD_MD5='md5'
134 | export _BM_CMD_COPY='xsel'
135 | fi
136 |
137 | # _BM_PRINT_LINE : This line is used to print datas
138 | # export _BM_PRINT_LINE="${_BM_PRINT_LINE:=${UNDERLINE}${GRAY_LIGHT}BM_URL${RESET} --> ${RESET}BM_TITLE ${GRAY_DARK}[BM_TAGS]\n${BOLD}${GRAY}BM_ACCEL ${GRAY_DARK}(BM_MD5)${RESET} - ${GRAY_DARK}Added: BM_DATE${RESET}}"
139 | export _BM_PRINT_LINE="${_BM_PRINT_LINE:=${BOLD}${GRAY}BM_ACCEL ${RESET}${DIM}-->${RESET} ${GRAY_LIGHT}BM_TITLE ${GRAY_DARK}${BOLD}[BM_TAGS]${RESET}\n${UNDERLINE}${DIM}BM_URL${RESET} - ${GRAY_DARK}Added: BM_DATE${RESET}}"
140 |
141 | # _BM_PRINT_LINE_ALTERNATIVE : This line is used to print datas
142 | export _BM_PRINT_LINE_ALTERNATIVE="${_BM_PRINT_LINE_ALTERNATIVE:=${BOLD}${GRAY}BM_ACCEL ${RESET}${DIM}-->${RESET} ${GRAY_LIGHT}BM_TITLE ${GRAY_DARK}${BOLD}[BM_TAGS]${RESET}\n${UNDERLINE}${DIM}BM_URL${RESET} ${GRAY_DARK}(BM_MD5)${RESET} - ${GRAY_DARK}Added: BM_DATE${RESET} - ${GRAY_DARK}Picture: BM_PICTURE${RESET}}"
143 |
144 | # _BM_PRINT_SCHEME : If set to no, bm will remove scheme from URL printing
145 | export _BM_PRINT_SCHEME=${_BM_PRINT_SCHEME:=true}
146 |
147 | # _BM_SEARCH_IGNORECASE : Ignore case if set when searching (overrided by -i)
148 | export _BM_SEARCH_IGNORECASE=${_BM_SEARCH_IGNORECASE:=false}
149 | }
150 |
151 | # slug creates a friendly URL like 'hello-world'
152 | slug() {
153 | iconv -f utf8 -t ascii//TRANSLIT | tr -cs '[:alnum:]\n' - | tr '[:upper:]' '[:lower:]' | sed 's|^-*||;s|-*$||'
154 | }
155 |
156 |
157 |
158 |
159 | # version
160 | RELEASE='35412a6'
161 | VERSION='0.6.7'
162 |
163 | #
164 | # Output usage info
165 | #
166 |
167 | usage() {
168 | if [ -z "${1:-}" ]; then
169 | cat < [desc] [tag...] [accelerator]
278 |
279 | # open the first bookmark matching
280 | $ bm open
281 | $ bm
282 |
283 | # search the bookmarks via full-text
284 | $ bm search
285 |
286 | # list tags
287 | $ bm tags
288 |
289 | # list bookmarks available
290 | $ bm list
291 | $ bm ls
292 | $ bm
293 |
294 | # display statistics about the bookmarks
295 | $ bm statistics
296 | $ bm stats
297 |
298 | # view bookmark screenshots in your default browser
299 | $ bm view design
300 | $ bm view
301 |
302 | # clear all bookmarks (now deprecated). Use -d instead.
303 | $ bm clear
304 |
305 | Options:
306 |
307 | -V output bm version
308 | -h output help information for new parameters
309 | -H output this help information
310 |
311 |
312 | EOF
313 | fi
314 | }
315 |
316 | getAccelMax() {
317 | # $2 ~ /^[[:SPACE:]]*:[[:SPACE:]]*[0-9][[:SPACE:]]*+$/ { n=gensub(/:([0-9])+/, "\\1", "g", $2); if (n>m) m=n; }
318 | # awk -F'|' '
319 | # BEGIN { m=0; }
320 | # $0 !~ /^[ ]*#/ && $2 ~ /^[:space:]*:[:space:]*[0-9]+[:space:]*$/ { sub(/:+/, "", $2); if ($2>m) m=$2; }
321 | # END { print m+1; }
322 | # ' "${_BM_BOOKMARK_FILE}"
323 | while read a; do
324 | (( ${a:=0} >= ${_max:=0} )) && (( _max=${a}+1 ))
325 | done <<< "$( awk -F'|' '$0 !~ /^[ ]*#/ && $3 ~ /^[:space:]*:[:space:]*[0-9]+[:space:]*$/ { sub(/:+/, "", $3); print $3; }' "${_BM_BOOKMARK_FILE}")"
326 | echo -n "${_max}"
327 | }
328 |
329 | backupBm() {
330 | if [ "${_BM_BOOKMARK_BACKUP,,}" = 'true' ]; then
331 | while [ ${count:=${_BM_BOOKMARK_BACKUP_VERSION}} -gt 0 ]; do
332 | cp -- "${_BM_BOOKMARK_BACKUP_FILE}.$(( count-1 ))" "${_BM_BOOKMARK_BACKUP_FILE}.$(( count-- ))" 2>&1 >/dev/null
333 | done
334 | cp -- "${_BM_BOOKMARK_FILE}" "${_BM_BOOKMARK_BACKUP_FILE}.0"
335 | fi
336 | }
337 |
338 | titleDl() {
339 | if command -v hxselect &>/dev/null ; then
340 | curl -Lks "${1:-}" 2>&1 | hxselect -ic title 2>/dev/null
341 | else
342 | curl -Lks "${1:-}" 2>&1 | sed '//I!d;/<\/title>/I!d;s;^[[:space:]]*\([^<]*\)<.*;\1;i'
343 | fi
344 | }
345 |
346 | saveUrl() {
347 | [[ "${__url}" =~ ^[[:space:]]*(f|ht)tps*://.*$ ]] || {
348 | if [ ${__F:=0} -eq 0 ]; then
349 | die "Your URL seems invalid '${__url}'. Use -F to force."
350 | else
351 | echo "Force adding invalid URL" >&2
352 | fi
353 | }
354 | local _sum="$(${_BM_CMD_MD5} <<< "${__url}")"
355 | if [ "${_BM_DUPS_DETECT,,}" = 'true' ]; then
356 | if [ ! -z "$(awk -F '|' '$0 !~ /^[ ]*#/ && $1 ~ /'"${_sum%% *}"'/' "${_BM_BOOKMARK_FILE}")" ]; then
357 | if [ ${__F:=0} -eq 0 ]; then
358 | die "URL is already in the Bookmark file"
359 | else
360 | echo "Force adding duplicate URL" >&2
361 | fi
362 | fi
363 | fi
364 | if [ "${_BM_GET_PAGE_TITLE,,}" = 'true' -a -z "${__T:=}" ]; then
365 | # if [ $( command -v hxselect &>/dev/null ) ]; then
366 | # __T="$( curl -Lks "${__url}" 2>&1 | hxselect -ic title )"
367 | # else
368 | # __T="$( curl -Lks "${__url}" 2>&1 | sed '//I!d;/<\/title>/I!d;s;^[[:space:]]*\([^<]*\)<.*;\1;i' )"
369 | # fi
370 | __T="$( titleDl "${__url}" )"
371 | fi
372 | [[ ! -z "${__T:=}" ]] && __T="${__T//\|/\\|}"
373 | backupBm
374 | [[ -z "${__T:=}" ]] && __T="$(slug <<< "${__url}")" # If no title => slug the url
375 | [[ -z "${__t:=}" ]] && __t='default' # Default tag is default
376 | [[ -z "${__A:=}" ]] && __A="$(getAccelMax)"
377 | [[ "${__A:0:1}" != ':' ]] && __A=":${__A}" # If no accel => Add a number
378 | echo "${_sum%% *}|$(date '+%FT%TZ')|${__A}|${__url}|${__T}|${__t}" >> "${_BM_BOOKMARK_FILE}" || die "Insert aborted into '${_BM_BOOKMARK_FILE}' !"
379 | echo "${__url} inserted into '${_BM_BOOKMARK_FILE}'"
380 | [[ ! -f "${_BM_SCREENSHOT_DIRECTORY}/${_sum%% *}.png" || ${__F:=0} -eq 1 ]] && { screenshot_take "${_BM_SCREENSHOT_DIRECTORY}/${_sum%% *}.png" "${__url}" & }
381 | [[ "${_BM_SCREENSHOT_WAIT,,}" = 'true' ]] && wait
382 | search_bookmarks "${__A}"
383 | }
384 |
385 | #
386 | # manage each line to print it
387 | #
388 |
389 | readLines() {
390 | IFS='|'
391 | while read m d a u T t; do
392 | _line="${_BM_PRINT_LINE}"
393 | [[ ${__z:=0} -eq 1 ]] && _line="${_BM_PRINT_LINE_ALTERNATIVE}"
394 | _line="${_line//BM_MD5/$m}"
395 | if [ "${_BM_PRINT_SCHEME,,}" = 'false' ]; then
396 | u="$(sed 's/^[[:space:]]*\(f\|ht\)tps*:\/\///' <<< "${u}")"
397 | fi
398 | _line="${_line//BM_URL/$u}"
399 | _line="${_line//BM_TITLE/$T}"
400 | _line="${_line//BM_TAGS/$t}"
401 | _line="${_line//BM_ACCEL/${a:=No-Accelerator}}"
402 | _line="${_line//BM_DATE/${d}}"
403 | local _pict="$(stat -c '%y' "${_BM_SCREENSHOT_DIRECTORY}/${m}.png" 2>/dev/null)"
404 | [[ ! -z "${_pict}" ]] && _pict="$(date '+%FT%TZ' --date "${_pict}")"
405 | _line="${_line//BM_PICTURE/${_pict:=None}}"
406 | echo -e "${_line}\n"
407 | done
408 | }
409 |
410 | #
411 | # List all bookmarks
412 | #
413 |
414 | list_bookmarks() {
415 | [[ ${__n:=0} -eq 1 ]] && { awk '$0 !~ /^[ ]*#/' "${_BM_BOOKMARK_FILE}" | sort -t'|' -k2 | readLines; return; }
416 | [[ ${__N:=0} -eq 1 ]] && { awk '$0 !~ /^[ ]*#/' "${_BM_BOOKMARK_FILE}" | sort -t'|' -k2 -r | readLines; return; }
417 | awk '$0 !~ /^[ ]*#/' "${_BM_BOOKMARK_FILE}" | readLines
418 | }
419 |
420 | #
421 | # Search all bookmarks with
422 | #
423 | search() {
424 | local _s=''
425 | [[ -z "${1:-}" ]] && list_bookmarks && return
426 | case "${1:0:1}" in
427 | :) _s=3; _ss=0 ;; # Accelerator
428 | +) _s="NF"; _ss=1 ;; # Tags
429 | =) _s=1; _ss=1 ;; # MD5 part
430 | /) _s=4; _ss=1 ;; # URL part
431 | *) _s=0; _ss=0 ;; # full text search
432 | esac
433 | [[ "${_BM_SEARCH_IGNORECASE,,}" = 'true' || ${__i:=0} -eq 1 ]] && local _ign=1
434 | awk -F'|' -vIgn=${_ign:=0} '
435 | BEGIN {
436 | if (Ign == 1) { s=tolower("'"${1:${_ss}}"'"); } else { s="'"${1:${_ss}}"'"; }
437 | }
438 | $0 !~ /^[ ]*#/ && (Ign == 0 && $'"${_s}"' ~ s) || (Ign ==1 && tolower($'"${_s}"') ~ s) {print $0;}
439 | ' "${_BM_BOOKMARK_FILE}"
440 |
441 | }
442 | search_bookmarks() {
443 | [[ ${__n:=0} -eq 1 ]] && { search "${@}" | sort -t'|' -k2 | readLines; return; }
444 | [[ ${__N:=0} -eq 1 ]] && { search "${@}" | sort -t'|' -k2 -r | readLines; return; }
445 | search "${@}" | readLines
446 | }
447 |
448 | #
449 | # Open first bookmark matching
450 | #
451 |
452 | recorded_picture() {
453 | local _lines="$(search "${@}")"
454 | if [ "${_BM_ASK_BEFORE_OPEN,,}" = 'true' -a ${__O:=0} -eq 0 -a ${__Y:=0} -eq 0 ]; then
455 | if [ $(wc -l <<< "${_lines}") -gt 1 ]; then
456 | read -p"More than one URL found. Open all Pictures ? [Y/N] : " -n1 _answer
457 | [[ "${_answer,,}" != 'y' ]] && die "\nUse -O to force the first URL or refine your search"
458 | fi
459 | fi
460 | local _all=''
461 | echo ''
462 | while read _nl; do
463 | readLines <<< "${_nl}"
464 | if [ "${_BM_OPEN_ALL,,}" = 'true' -o ${__Y:=0} -eq 1 ]; then
465 | _all="${_BM_SCREENSHOT_DIRECTORY}/$(awk -F'|' '{print $1}' <<< "${_nl}").png ${_all}"
466 | else
467 | "${_BM_CMD_IMAGE_OPEN}" "${_BM_SCREENSHOT_DIRECTORY}/$(awk -F'|' '{print $1}' <<< "${_nl}").png"
468 | [[ "${_BM_OPEN_FIRST,,}" = 'true' || ${__O:=0} -eq 1 ]] && exit 0
469 | fi
470 | done <<< "$(echo -e "${_lines}")"
471 | [[ "${_BM_OPEN_ALL,,}" = 'true' || ${__Y:=0} -eq 1 ]] && "${_BM_CMD_IMAGE_OPEN}" "${_all}"
472 | }
473 |
474 | download_title() {
475 | local _lines="$(search "${@}")"
476 | if [ "${_BM_ASK_BEFORE_OPEN,,}" = 'true' -a ${__O:=0} -eq 0 -a ${__Y:=0} -eq 0 ]; then
477 | if [ $(wc -l <<< "${_lines}") -gt 1 ]; then
478 | read -p"More than one URL found. Download Title for all URLs ? [Y/N] : " -n1 _answer
479 | [[ "${_answer,,}" != 'y' ]] && die "\nUse -O to force the first URL or refine your search"
480 | fi
481 | fi
482 | local _all=''
483 | echo ''
484 | while read _nl; do
485 | readLines <<< "${_nl}"
486 | local u="$(awk -F'|' '{print $4}' <<< "${_nl}")"
487 | if [ "${_BM_OPEN_ALL,,}" = 'true' -o ${__Y:=0} -eq 1 ]; then
488 | echo "${u} --> $( titleDl "${u}" )"
489 | else
490 | echo "${u} --> $( titleDl "${u}" )"
491 | [[ "${_BM_OPEN_FIRST,,}" = 'true' || ${__O:=0} -eq 1 ]] && exit 0
492 | fi
493 | done <<< "$(echo -e "${_lines}")"
494 | }
495 |
496 | open_bookmark() {
497 | local _lines="$(search "${@}")"
498 | if [ "${_BM_ASK_BEFORE_OPEN,,}" = 'true' -a ${__O:=0} -eq 0 -a ${__Y:=0} -eq 0 ]; then
499 | if [ $(wc -l <<< "${_lines}") -gt 1 ]; then
500 | read -p"More than one URL found. Open all ? [Y/N] : " -n1 _answer
501 | [[ "${_answer,,}" != 'y' ]] && die "\nUse -O to force the first URL or refine your search"
502 | fi
503 | fi
504 | local _all=''
505 | while read _nl; do
506 | readLines <<< "${_nl}"
507 | if [ "${_BM_OPEN_ALL,,}" = 'true' -o ${__Y:=0} -eq 1 ]; then
508 | _all="$(awk -F'|' '{print $4}' <<< "${_nl}") ${_all}"
509 | else
510 | "${_BM_CMD_OPEN}" "$(awk -F'|' '{print $4}' <<< "${_nl}")"
511 | [[ "${_BM_OPEN_FIRST,,}" = 'true' || ${__O:=0} -eq 1 ]] && exit 0
512 | fi
513 | done <<< "$(echo -e "${_lines}")"
514 | [[ "${_BM_OPEN_ALL,,}" = 'true' || ${__Y:=0} -eq 1 ]] && "${_BM_CMD_OPEN}" "${_all}"
515 | }
516 |
517 | copy_bookmark() {
518 | local _lines="$(search "${@}")"
519 | if [ "${_BM_ASK_BEFORE_OPEN,,}" = 'true' -a ${__X:=0} -eq 0 -a ${__Y:=0} -eq 0 ]; then
520 | if [ $(wc -l <<< "${_lines}") -gt 1 ]; then
521 | read -p"More than one URL found. Copy all ? [Y/N] : " -n1 _answer
522 | [[ "${_answer,,}" != 'y' ]] && die "\nUse -X to force the first URL or refine your search"
523 | fi
524 | fi
525 | local _all=''
526 | while read _nl; do
527 | readLines <<< "${_nl}"
528 | if [ "${_BM_OPEN_ALL,,}" = 'true' -o ${__Y:=0} -eq 1 ]; then
529 | _all="$(awk -F'|' '{print $4}' <<< "${_nl}") ${_all}"
530 | else
531 | awk -F'|' '{print $4}' <<< "${_nl}" | "${_BM_CMD_COPY}"
532 | awk -F'|' '{print $4}' <<< "${_nl}" | "${_BM_CMD_COPY}" -b
533 | [[ "${_BM_OPEN_FIRST,,}" = 'true' || ${__X:=0} -eq 1 ]] && exit 0
534 | fi
535 | done <<< "$(echo -e "${_lines}")"
536 | [[ "${_BM_OPEN_ALL,,}" = 'true' || ${__Y:=0} -eq 1 ]] && "${_BM_CMD_COPY}" <<< "${_all}"
537 | [[ "${_BM_OPEN_ALL,,}" = 'true' || ${__Y:=0} -eq 1 ]] && "${_BM_CMD_COPY}" -b <<< "${_all}"
538 | }
539 |
540 | delete_bookmark() {
541 | [[ -z "${@//[ ]/}" ]] && die "You MUST give an argument !"
542 | local _lines="$(search "${@}")"
543 | if [ "${_BM_DELETE_ALLOWED,,}" = 'true' ]; then
544 | while read _nl; do readLines <<< "${_nl}"; done <<< "$(echo -e "${_lines}")"
545 | if [ "${_BM_ASK_BEFORE_OPEN,,}" = 'true' -a ${__D:=0} -eq 0 -a ${__Y:=0} -eq 0 ]; then
546 | if [ $(wc -l <<< "${_lines}") -ge 1 ]; then
547 | read -p"You're about to delete entry(ies). Ready ? [Y/N] : " -n1 _answer
548 | [[ "${_answer,,}" != 'y' ]] && die "\nUse -D to force the backup if not configured."
549 | echo ''
550 | fi
551 | fi
552 | backupBm
553 | local _all=''
554 | while read _nl; do
555 | if [ "${_BM_DELETE_TO_FILE,,}" = 'true' -o ${__D:=0} -eq 1 ]; then
556 | echo "${_nl}" >> "${_BM_DELETE_FILE}"
557 | fi
558 | [[ "${_BM_DELETE_PICTURE,,}" = 'true' || ${__p:=0} -eq 1 ]] && rm -f -- "${_BM_SCREENSHOT_DIRECTORY}/${_nl%%|*}.png"
559 | IFS='|' read m d a u T t <<< "${_nl}"
560 | sed -i -e '/^'"${m}.*${u//\//\\/}.*${t//\//\\/}"'$/d' "${_BM_BOOKMARK_FILE}"
561 | done <<< "$(echo -e "${_lines}")"
562 | else
563 | die "You're not allowed to delete entries. Change the _BM_DELETE_ALLOWED to true !"
564 | fi
565 | }
566 |
567 | edit_bookmark() {
568 | echo -e "You're about to open your '${_BM_BOOKMARK_FILE}' file with your \$EDITOR.\n\n/!\ Press any key to continue, or CTRL+C to abort. /!\ "
569 | read -n1 toto
570 | ${EDITOR:=vi} "${_BM_BOOKMARK_FILE}"
571 | }
572 |
573 | #
574 | # Diplay some statistics about the bookmarks
575 | #
576 | stats() {
577 | echo "===== Configuration ====="
578 | echo "Bookmark file : ${_BM_BOOKMARK_FILE}"
579 | echo "Config file : ${_BM_CONFIG_FILE}$([[ ! -e "${_BM_CONFIG_FILE}" ]] && echo " (but doesn't exist)")"
580 | echo "Trash file : ${_BM_DELETE_FILE}$([[ ! -e "${_BM_DELETE_FILE}" ]] && echo " (but doesn't exist)")"
581 | echo "Screenshot directory : ${_BM_SCREENSHOT_DIRECTORY}"
582 | echo "Backup file(s) : ${_BM_BOOKMARK_BACKUP_FILE}*"
583 | for i in "${_BM_BOOKMARK_BACKUP_FILE}"*; do
584 | echo " ${i}"
585 | done
586 | echo -e "\n===== Statistics ====="
587 | readarray -t lines < "${_BM_BOOKMARK_FILE}"
588 | echo "# of Bookmarks : ${#lines[@]}"
589 | echo "# of Duplicate : $(awk -F'|' '$0 !~ /^[ ]*#/ {print $1}' "${_BM_BOOKMARK_FILE}" |sort |uniq -d |wc -l)"
590 | local tags="$(awk -F'|' '$0 !~ /^[ ]*#/ {print $NF}' "${_BM_BOOKMARK_FILE}" | sed -e 's/\([[:space:]]*,[[:space:]]*\)/\n/g')"
591 |
592 | echo "# of tags : $( sort -u <<< "${tags,,}" |wc -l)"
593 | echo "Top 14 tags used :"
594 | local nli=0;local pa=0
595 | (
596 | sort <<< "${tags,,}" | uniq -c | sort -nr | while read n t; do
597 | (( nli++ ));[[ ${nli} -gt 7 ]] && nli=1 && echo ''
598 | (( pa++ ));[[ ${pa} -gt 14 ]] && break
599 | echo -n "${t// / }:${n} "
600 | done
601 | echo ''
602 | ) | column -t -x -c 7
603 | echo "# of Pictures : $(ls -1 "${_BM_SCREENSHOT_DIRECTORY}"/*.png |wc -l) [# of files in ${_BM_SCREENSHOT_DIRECTORY}:$(ls -1 "${_BM_SCREENSHOT_DIRECTORY}"/* |wc -l)]"
604 | echo "All Pictures size : $(du -sh "${_BM_SCREENSHOT_DIRECTORY}" | awk '{print $1}')"
605 | local orphaned="$( cd "${_BM_SCREENSHOT_DIRECTORY}" && for i in *; do [[ -z "$(sed -e '/'"${i%%.*}"'/!d' "${_BM_BOOKMARK_FILE}")" ]] && ((orph++)); done; echo "${orph:=0}" )"
606 | local nopics="$( while read i; do [[ ! -f "${_BM_SCREENSHOT_DIRECTORY}/${i%%|*}.png" ]] && ((nopics++)); done <<< ${lines[@]}; echo "${nopics:=0}" )"
607 | echo "Bookmark Without Pic : ${nopics}"
608 | echo "Orphaned pictures : ${orphaned}"
609 | [[ ${__p:=0} -eq 1 ]] && { echo -e "\n===== Orphaned ====="; echo "List of orphaned pictures :"; cd "${_BM_SCREENSHOT_DIRECTORY}" && for i in *; do [[ -z "$(sed -e '/'"${i%%.*}"'/!d' "${_BM_BOOKMARK_FILE}")" ]] && echo " - ${_BM_SCREENSHOT_DIRECTORY}/${i} [Trashed URL should be: $(awk -F'|' 'BEGIN{l="Unknown"} ($1 ~ /'"${i%%.*}"'/) {l=$4;} END {print l}' "${_BM_DELETE_FILE}")]"; done; };
610 | }
611 |
612 | #
613 | # Output tags.
614 | #
615 |
616 | list_tags() {
617 | local tags="$(awk -F'|' '$0 !~ /^[ ]*#/ {print $NF}' "${_BM_BOOKMARK_FILE}" | sed -e 's/\([[:space:]]*,[[:space:]]*\)/\n/g')"
618 | local nli=0
619 | (
620 | sort <<< "${tags,,}" | uniq -c | sort -nr | while read n t; do
621 | (( nli++ ));[[ ${nli} -gt 7 ]] && nli=1 && echo ''
622 | echo -n "${t// / }:${n} "
623 | done
624 | echo ''
625 | ) | column -t -x -c 7
626 | }
627 |
628 | #
629 | # Stylesheet
630 | #
631 |
632 | style() {
633 | cat <
635 | * {
636 | -webkit-box-sizing: border-box;
637 | -moz-box-sizing: border-box;
638 | box-sizing: border-box;
639 | }
640 | body {
641 | padding: 50px 0 5px 50px;
642 | background: #1f1f1f url(${_BM_SCREENSHOT_DIRECTORY}/black-Linen.png);
643 | font: 12px "Helvetica Neue", Helvetica, Arial, sans-serif;
644 | }
645 | .bm {
646 | position: relative;
647 | float: left;
648 | margin: 15px;
649 | padding: 1px;
650 | opacity: 1;
651 | border: 15px solid black;
652 | border-radius: 5px;
653 | -webkit-border-radius: 5px;
654 | -moz-border-radius: 5px;
655 | -webkit-transition: -webkit-box-shadow 600ms;
656 | -moz-transition: -webkit-box-shadow 600ms;
657 | -webkit-box-shadow: 0 0 1px 0 #555, 0 0 10px rgba(0,0,0,.5);
658 | -moz-box-shadow: 0 0 1px 0 #555, 0 0 10px rgba(0,0,0,.5);
659 | overflow: hidden;
660 | }
661 | .bm:hover {
662 | -webkit-box-shadow: 0 0 40px #1ab0ff
663 | , 0 0 3px #06bdff
664 | , 0 1px 1px #4ee2ff
665 | , 0 1px 0 #fff;
666 | -moz-box-shadow: 0 0 40px #1ab0ff
667 | , 0 0 3px #06bdff
668 | , 0 1px 1px #4ee2ff
669 | , 0 1px 0 #fff;
670 | }
671 | .bm:hover img {
672 | opacity: 1;
673 | }
674 | .bm img {
675 | width: 200px;
676 | height: 150px;
677 | opacity: .5;
678 | border-radius: 5px;
679 | -webkit-border-radius: 5px;
680 | -moz-border-radius: 5px;
681 | -webkit-transition: opacity 200ms;
682 | -moz-transition: opacity 200ms;
683 | }
684 | .bm p {
685 | margin: 0;
686 | padding: 10px;
687 | width: 100%;
688 | background: rgba(0,0,0,.75);
689 | position: absolute;
690 | left: 0;
691 | color: white;
692 | letter-spacing: 1px;
693 | bottom: -50px;
694 | -webkit-font-smoothing: antialiased;
695 | -webkit-transition: bottom 200ms ease-in;
696 | }
697 | .bm:hover p {
698 | bottom: 0;
699 | }
700 |
701 | EOF
702 | }
703 |
704 | #
705 | # Generate bookmark screenshots
706 | #
707 |
708 | screenshot_take() {
709 | if [ "${_BM_SCREENSHOT_GET,,}" = 'true' -o ${__p:=0} -eq 1 ]; then
710 | [[ ! -d "${_BM_SCREENSHOT_DIRECTORY}" ]] && { mkdir -p "${_BM_SCREENSHOT_DIRECTORY}" || die "Can't create thumbnail directory." ; }
711 | [[ ! -z "${_BM_CMD_PRE_CAPTURE}" ]] && { local _pre="${_BM_CMD_PRE_CAPTURE//\{FILE\}/${1}}"; _pre="${_pre//\{URL\}/${2}}"; ${_pre} ; }
712 | local _cmd="${_BM_CMD_CAPTURE//\{FILE\}/${1}}"; _cmd="${_cmd//\{URL\}/${2}}";
713 | local _args="${_BM_CMD_CAPTURE_ARGS//\{FILE\}/${1}}"; _args="${_args//\{URL\}/${2}}";
714 | eval ${_cmd} ${_args}
715 | [[ ! -z "${_BM_CMD_POST_CAPTURE}" ]] && { local _post="${_BM_CMD_POST_CAPTURE//\{FILE\}/${1}}"; _post="${_post//\{URL\}/${2}}"; ${_post} ; }
716 | fi
717 | }
718 |
719 | picturize() {
720 | if [ -z "${1:-}" ]; then
721 | awk -F'|' '$0 !~ /^[ ]*#/ {print $1,$4;}' "${_BM_BOOKMARK_FILE}" | while read m u; do
722 | [[ ! -f "${_BM_SCREENSHOT_DIRECTORY}/${m}.png" || ${__F:=0} -eq 1 ]] && { screenshot_take "${_BM_SCREENSHOT_DIRECTORY}/${m}.png" "${u}" & }
723 | [[ "${_BM_SCREENSHOT_WAIT,,}" = 'true' ]] && wait
724 | done
725 | else
726 | local _lines="$(search "${@}")"
727 | if [ "${_BM_ASK_BEFORE_OPEN,,}" = 'true' -a ${__O:=0} -eq 0 -a ${__Y:=0} -eq 0 ]; then
728 | if [ $(wc -l <<< "${_lines}") -gt 1 ]; then
729 | read -p"More than one URL found. Open all ? [Y/N] : " -n1 _answer
730 | [[ "${_answer,,}" != 'y' ]] && die "\nUse -O to force the first URL or refine your search"
731 | fi
732 | fi
733 | local _all=''
734 | while read _nl; do
735 | readLines <<< "${_nl}"
736 | if [ "${_BM_OPEN_ALL,,}" = 'true' -o ${__Y:=0} -eq 1 ]; then
737 | IFS='|' read m d a u b <<< "${_nl}"
738 | screenshot_take "${_BM_SCREENSHOT_DIRECTORY}/${m}.png" "${u}" &
739 | else
740 | IFS='|' read m d a u b <<< "${_nl}"
741 | screenshot_take "${_BM_SCREENSHOT_DIRECTORY}/${m}.png" "${u}" &
742 | [[ "${_BM_OPEN_FIRST,,}" = 'true' || ${__O:=0} -eq 1 ]] && exit 0
743 | fi
744 | done <<< "$(echo -e "${_lines}")"
745 | fi
746 | }
747 |
748 | bookmark_generator() {
749 | [[ ! -f "${_BM_SCREENSHOT_DIRECTORY}/black-Linen.png" && -f "/usr/share/bm/black-Linen.png" ]] && cp "/usr/share/bm/black-Linen.png" "${_BM_SCREENSHOT_DIRECTORY}/black-Linen.png"
750 | echo "bm v${VERSION} : all your bookmarks" > "${1:-${_BM_HTML_FILE}}"
751 | style >> "${1:-${_BM_HTML_FILE}}"
752 | echo "" >> "${1:-${_BM_HTML_FILE}}"
753 | # search "${2:-}" | while IFS='|' read m a u T t d; do
754 | awk '$0 !~ /^[ ]*#/' "${_BM_BOOKMARK_FILE}" | while IFS='|' read m d a u T t; do
755 | echo " " >> "${1:-${_BM_HTML_FILE}}"
759 | done
760 | echo "" >> "${1:-${_BM_HTML_FILE}}"
761 | [[ ${__O:=0} -eq 1 ]] && "${_BM_CMD_OPEN}" "${1:-${_BM_HTML_FILE}}"
762 | }
763 |
764 | #
765 | # die print message to stderr and exit
766 | #
767 |
768 | die() {
769 | echo -e "${@}" >&2
770 | exit 1
771 | }
772 |
773 |
774 | #
775 | # checkBinaries check the script is able to run and give hints
776 | #
777 |
778 | checkBinaries() {
779 | if [ ${#} -ne 0 ]; then
780 | local cmdErr="${@}"
781 | else
782 | local cmdErr="sed awk date iconv cat curl ${_BM_CMD_OPEN} ${_BM_CMD_MD5} column"
783 | fi
784 | set ${cmdErr}
785 | while [ ${#} -ne 0 ]; do
786 | if ! command -v "${1:-}" &>/dev/null; then
787 | echo "command not found: ${1}" >&2
788 | local rc=1
789 | fi
790 | shift
791 | done
792 | [[ ${rc:=0} -ne 0 ]] && die "At least one command is missing. Please install it before using bm."
793 | # Checking sed
794 | local rc=1
795 | [[ ! -f "/tmp/sedtest.$$" ]] && \
796 | echo -n 'toto' > "/tmp/sedtest.$$" && \
797 | sed -i.bak -e 's;^toto$;tata;' "/tmp/sedtest.$$" && \
798 | [[ -f "/tmp/sedtest.$$.bak" ]] && \
799 | grep -q "tata" "/tmp/sedtest.$$" && \
800 | rc=0 && \
801 | rm -f "/tmp/sedtest.$$" "/tmp/sedtest.$$.bak"
802 | [[ ${rc} -ne 0 ]] && die "sed seems to not handle -i argument properly, please check"
803 | }
804 |
805 | #
806 | # defineColors generate the variables to use to colorize the output
807 | #
808 |
809 | defineColors() {
810 | export BLACK="\e[30m"; export BLACK_LIGHT="\e[90m"; export GRAY_DARK="${BLACK_LIGHT}"
811 | export RED="\e[31m"; export RED_LIGHT="\e[91m"
812 | export GREEN="\e[32m"; export GREEN_LIGHT="\e[92m"
813 | export YELLOW="\e[33m"; export YELLOW_LIGHT="\e[93m"
814 | export BLUE="\e[34m"; export BLUE_LIGHT="\e[94m"
815 | export MAGENTA="\e[35m"; export MAGENTA_LIGHT="\e[95m"
816 | export CYAN="\e[36m"; export CYAN_LIGHT="\e[96m"
817 | export GRAY="\e[37m"; export GRAY_LIGHT="\e[97m"; export WHITE="${GRAY_LIGHT}"
818 |
819 | export RESET="\e[0m"
820 | export BOLD="\e[1m"; export BOLD_RESET="\e[21m"
821 | export DIM="\e[2m"; export DIM_RESET="\e[22m"
822 | export UNDERLINE="\e[4m"; export UNDERLINE_RESET="\e[24m"
823 | export INVERT="\e[7m"; export INVERT_RESET="\e[27m"
824 | if [ ! -z "${1:-}" ]; then
825 | echo "Use the following colors to fit your needs :"
826 | (
827 | echo -e "${RESET}${BLACK}BLACK${RESET} - ${BLACK_LIGHT}BLACK_LIGHT${RESET} - ${BOLD}${BLACK}BOLD BLACK${RESET} - ${DIM}${BLACK}DIM BLACK${RESET}"
828 | echo -e "${RESET}${RED}RED${RESET} - ${RED_LIGHT}RED_LIGHT${RESET} - ${BOLD}${RED}BOLD RED${RESET} - ${DIM}${RED}DIM RED${RESET}"
829 | echo -e "${RESET}${GREEN}GREEN${RESET} - ${GREEN_LIGHT}GREEN_LIGHT${RESET} - ${BOLD}${GREEN}BOLD GREEN${RESET} - ${DIM}${GREEN}DIM GREEN${RESET}"
830 | echo -e "${RESET}${YELLOW}YELLOW${RESET} - ${YELLOW_LIGHT}YELLOW_LIGHT${RESET} - ${BOLD}${YELLOW}BOLD YELLOW${RESET} - ${DIM}${YELLOW}DIM YELLOW${RESET}"
831 | echo -e "${RESET}${BLUE}BLUE${RESET} - ${BLUE_LIGHT}BLUE_LIGHT${RESET} - ${BOLD}${BLUE}BOLD BLUE${RESET} - ${DIM}${BLUE}DIM BLUE${RESET}"
832 | echo -e "${RESET}${MAGENTA}MAGENTA${RESET} - ${MAGENTA_LIGHT}MAGENTA_LIGHT${RESET} - ${BOLD}${MAGENTA}BOLD MAGENTA${RESET} - ${DIM}${MAGENTA}DIM MAGENTA${RESET}"
833 | echo -e "${RESET}${CYAN}CYAN${RESET} - ${CYAN_LIGHT}CYAN_LIGHT${RESET} - ${BOLD}${CYAN}BOLD CYAN${RESET} - ${DIM}${CYAN}DIM CYAN${RESET}"
834 | echo -e "${RESET}${GRAY}GRAY${RESET} - ${GRAY_LIGHT}GRAY_LIGHT${RESET} - ${BOLD}${GRAY}BOLD GRAY${RESET} - ${DIM}${GRAY}DIM GRAY${RESET}"
835 | echo -e "${RESET}${GRAY_DARK}GRAY_DARK${RESET} - ${WHITE}WHITE${RESET}"
836 | ) | column -t
837 | echo -e "You could also use the ${UNDERLINE}UNDERLINE, the ${INVERT}INVERT and the ${RESET}RESET variable. INVERT_RESET and UNDERLINE_RESET also available"
838 | exit 0
839 | fi
840 | }
841 |
842 | ##############################################################################
843 | # MAIN
844 | ##############################################################################
845 |
846 | ##################### TRANSITIONNAL ############################
847 | _regex='^(help|version|tags|ls|list|search|open|add|view|stats|statistics|clear|colors)$'
848 | if [[ ${1:-} =~ ${_regex} ]]; then
849 | case "$1" in
850 | tags) __L=1 ;;
851 | ls|list) __l=1 ;;
852 | search) __s=1; __search="${@:2}" ;;
853 | open) __o=1; __open="${@:2}";;
854 | add) __a=1; __url="${2:-}"; __T="${3:-}"; __t="${4:-}"; __A="${5:-}";;
855 | view) __r=1; __search="${@:2}" ;;
856 | stats|statistics) __S=1 ;;
857 | clear) die "This now a deprecated feature. Use -d instead." ;;
858 | colors) __C=1;;
859 | help) usage 1;exit 0;;
860 | version) echo -n "${0} v${VERSION}";exit 0;;
861 | esac
862 | else
863 | #q -c config file
864 | # -C colors print ==> exit
865 | # -b bookmark file
866 | # -d delete
867 | # -D deletefile if set override _BM_DELETE_TO_FILE to true
868 | # -w working dir
869 | # -a add url =/= -l, -s, -S, -O, -o, -x, -X, -g, -C
870 | # -A Accelerator
871 | # -T title
872 | # -t tags
873 | # -s search
874 | # -S stats
875 | # -l list all url
876 | # -o open
877 | # -O open first
878 | # -x copy to clipboard
879 | # -X copy first URL
880 | # -h help
881 | # -H more help
882 | # -v version
883 | # -V more version ?
884 | # -g generate html file
885 | # -G use this file
886 | # -g -g generate 1 file per tags
887 | # used : AaBbCcDdE-F-GgHh-i----Ll--NnOoPp-q-rSsTt--Vv-wXxY--z----------
888 | # available : ---------e-f----I-JjKk--Mm------Q-R-----Uu--W----yZ-0123456789
889 | while getopts ":a:A:b:c:d:G:o:P:q:r:s:t:T:w:x:BCDEFghHilLnNOpPSvVXYz" option; do
890 | case ${option} in
891 | a) __a=1; __url="${OPTARG}";; # Add url to bookmark
892 | A) __A="${OPTARG}";; # AcceleratoR
893 | b) __b="${OPTARG}";; # Bookmark file
894 | B) __B=1;; # Don't load the default config file
895 | c) __c="${OPTARG}";; # Config file
896 | C) __C=1;; # Print color table
897 | d) __d=1; __del="${OPTARG}";; # Config file
898 | D) __D=1;; # Print color table
899 | E) __E=1;; # Open the bm.lnk file with the $EDITOR
900 | F) __F=1;; # Force the add or delete or picture
901 | g) (( __g++ ));; # generate html file(s)
902 | G) __G=1; __file="${OPTARG}";; # Generate this file (only for g=1)
903 | h) usage; exit 0;; # Help
904 | H) usage 1; exit 0;; # Help
905 | i) __i=1;; # Ignore case when searching
906 | l) __l=1;; # List all bookmarks
907 | L) __L=1;; # List all tags
908 | n) __n=1;; # sort by date
909 | N) __N=1;; # sort by date (reverse)
910 | o) __o=1; __open="${OPTARG}";; # Open
911 | O) __O=1;; # Open First
912 | p) __p=1;; # Take a screenshot
913 | P) __P=1; __search="${OPTARG}";; # Take all screenshot
914 | q) __q=1; __search="${OPTARG}";; # Search
915 | r) __r=1; __search="${OPTARG}";; # Search
916 | s) __s=1; __search="${OPTARG}";; # Search
917 | S) __S=1;; # Print Statistics
918 | t) __t="${OPTARG}";; # tags for a URL
919 | T) __T="${OPTARG}";; # Title for a URL
920 | v|V) echo -n "${0} v${VERSION}"; [[ "${option}" = 'V' ]] && echo -n " [commit: ${RELEASE}]"; echo ''; exit 0;;
921 | w) __w="${OPTARG}";; # Working directory
922 | x) __x=1; __copy="${OPTARG}";; # Copy
923 | X) __X=1;; # Copy First
924 | Y) __Y=1;; # Open/copy All
925 | z) __z=1;; # Alternative print listing
926 | :) echo "Missing argument for '-${OPTARG}'" >&2 ; exit 1 ;;
927 | ?) echo "Argument unknown '-${OPTARG}'" >&2 ; exit 1 ;; # usage;;
928 | *) echo "Argument unknown '-${option}'" >&2 ; exit 1 ;; # usage;;
929 | esac
930 | done
931 | fi
932 |
933 | # Parsing args is done, Starting to work, so check if binaries are here
934 | checkBinaries
935 |
936 | # defineColors MUST be called before the config() or _BM_PRINT_LINE will be in trouble.
937 | defineColors
938 | # Before loading config, checking if working dir exist...
939 | if [ ! -z "${__w:=}" -a ! -d "${__w}" ]; then
940 | die "Working directory '${__w}' doesn't exist !" >&2
941 | fi
942 | # Loading config
943 | config "${__c}"
944 | [[ ! -z "${__b:=}" ]] && export _BM_BOOKMARK_FILE="${__b}"
945 |
946 | # Following config, we maybe not have to check the capture tool
947 | [[ ${_BM_CMD_CAPTURE_CHECK} ]] && checkBinaries "${_BM_CMD_CAPTURE}"
948 |
949 | # If no bookmark file exist, create one if allowed
950 | if [ ! -f "${_BM_BOOKMARK_FILE}" -a "${_BM_CREATE_BOOKMARK_FILE,,}" = 'true' ]; then
951 | # Remember fields : 1=md5, 2=date, 2=accel, 3=url, 4=title, 5=tags
952 | echo "bd8b3eff7fa82a0382a3e7576c5363b6|$(date '+%FT%TZ')|:bm|https://github.com/Flyounet/bm/|bm a cool enhanced bookmark tool for your console|default,shell" >> "${_BM_BOOKMARK_FILE}"
953 | echo "2981b5cae113491ddb18e0d51454f0d9|$(date '+%FT%TZ')|:bmtj|https://github.com/tj/bm/|The original bm : a cool bookmark tool for your console|default,shell" >> "${_BM_BOOKMARK_FILE}"
954 | fi
955 |
956 | # Starting to work with args. If none probably list...
957 | [[ ${#} -eq 0 && "${_BM_NO_ARGS_FORCE_HELP,,}" = 'true' ]] && { usage ; exit; }
958 |
959 | # Only one action at a time
960 | if [ $(( ${__a:=0} + ${__C:=0} + ${__d:=0} + ${__E:=0} + ${__g:=0} + ${__l:=0} + ${__L:=0} + ${__o:=0} + ${__P:=0} + ${__q:=0} + ${__r:=0} + ${__s:=0} + ${__S:=0} + ${__x:=0} )) -gt 1 ]; then
961 | echo "You have to choose between -a, -C, -d, -E, -g, -l, -L, -o, -P, -q, -r, -s, -S, -x" >&2
962 | echo "Use -h for help" >&2
963 | exit 0
964 | fi
965 | if [ $(( ${__O:=0} + ${__Y:=0} + ${__X:=0} )) -gt 1 ]; then
966 | echo "You have to choose between -O, -X, -Y" >&2
967 | echo "Use -h for help" >&2
968 | exit 0
969 | fi
970 |
971 | # Executing actions
972 | [[ ${__a} -eq 1 ]] && { saveUrl ; exit ; }
973 | [[ ${__C} -eq 1 ]] && { defineColors 1 ; exit ; }
974 | [[ ${__d} -eq 1 ]] && { delete_bookmark "${__del}"; exit ; }
975 | [[ ${__g} -ge 1 ]] && { bookmark_generator "${__file:=}" ''; exit ; }
976 | [[ ${__l} -eq 1 ]] && { search ; exit; }
977 | [[ ${__L} -eq 1 ]] && { list_tags ; exit; }
978 | [[ ${__o} -eq 1 ]] && { open_bookmark "${__open}" ; exit; }
979 | [[ ${__P} -eq 1 ]] && { picturize "${__search}" ; exit; }
980 | [[ ${__r} -eq 1 ]] && { recorded_picture "${__search}" ; exit; }
981 | [[ ${__q} -eq 1 ]] && { download_title "${__search}" ; exit; }
982 | [[ ${__s} -eq 1 ]] && { search_bookmarks "${__search}" ; exit; }
983 | [[ ${__S} -eq 1 ]] && { stats ; exit; }
984 | [[ ${__x} -eq 1 ]] && { copy_bookmark "${__copy}" ; exit; }
985 | [[ ${__E} -eq 1 ]] && { edit_bookmark ; exit; }
986 | search
987 |
988 | # GitHub @ Fri, 14 Oct 2016 22:30:47 +0200 : $Id: 46fe3b0647de7136b877dec1c34202b15807db2e $
989 |
--------------------------------------------------------------------------------
/licenses.txt:
--------------------------------------------------------------------------------
1 | ##############################################################################
2 |
3 |
4 |
5 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
6 | Version 2, December 2004
7 |
8 | Copyright (C) 2004 Sam Hocevar
9 |
10 | Everyone is permitted to copy and distribute verbatim or modified
11 | copies of this license document, and changing it is allowed as long
12 | as the name is changed.
13 |
14 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
15 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
16 |
17 | 0. You just DO WHAT THE FUCK YOU WANT TO.
18 |
19 |
20 |
21 | ##############################################################################
22 |
23 |
24 |
25 | Demerden Sie Sich License
26 |
27 | Version 1, 15 Mars 2010
28 |
29 | Copyright © 2010 Flyounet.
30 |
31 | Chacun est autorisé à copier et distribuer des copies conformes de ce document de licence, mais toute modification en est proscrite.
32 | DSSL : Demerden Sie Sich License
33 | Préambule :
34 |
35 | La Licence Démerdez-vous («Demerden Sie Sich License») est une licence libre, en «copyleft», destinée aux œuvres logicielles et d’autres types de travaux. Elle s'appuie sur des fondamentaux comme la Licence Lis ce Putain de Manuel ("Read This Fucking Manual License").
36 |
37 | «Cette Licence» est auto-récursive, puisqu'elle est, elle même, assujetie à la «Demerden Sie Sich License».
38 | Termes et Conditions :
39 | Article 0. Définitions.
40 |
41 | «Cette Licence» se réfère à la version 1 de la «Demerden Sie Sich License» (le texte original en français).
42 | «Démerder», se réfère au sens de se «débrouiller». A aucun moment «cette Licence» ne vous demandera de vous enduire (vous ou votre œuvre) d'excréments humains (ni même animal).
43 | «Œuvre» est aussi appelée «travail» (quelques fois, l'extension «de sagouin» peut lui être apposée), «programme» ou tout autre terme relatif à ce qui a été effectué. Ainsi, une «documentation» ou un «manuel» peut être considéré comme une œuvre.
44 | «Auteur» signifie que la personne (ou groupe de personnes), qui utilise «cette Licence», se lave complètement les mains de la façon dont vous utiliserez son œuvre.
45 |
46 | Article 1. Permissions de base.
47 |
48 | Tous les droits accordés suivant «cette Licence» le sont jusqu’au terme de la volonté de son «Auteur». «Cette Licence» affirme explicitement votre permission illimitée de vous en sortir par vous même. «Cette Licence» reconnait vos propres droits d’usage raisonnable (droit de poser des questions à l'«Auteur», droit de discuter avec qui vous voulez de «cette Licence» et du contenu de l'œuvre).
49 |
50 | Vous pouvez critiquer, vitupérer et propager votre rancœur sans condition envers «cette Licence» ou l'œuvre courverte par celle-ci.
51 |
52 | L'«Auteur» peut à tout moment décider de passer outre «cette Licence» en accordant de l'aide (qui peut être elle-même couverte par «cette Licence») efficace ou non. Le fait d'apporter de l'aide n'enlève pas «cette Licence» à l'œuvre à laquelle elle est liée.
53 | Article 2. Limitation de responsabilité.
54 |
55 | L'«Auteur» peut-être considéré comme irresponsable et il incombe à l'utilisateur en priorité de se «démerder» par lui même.
56 |
57 | FIN DES TERMES ET CONDITIONS.
58 | Comment appliquer ces termes à vos nouvelles œuvres
59 |
60 | Si vous développez ou créez une nouvelle œuvre et voulez être le plus possible tranquille (histoire que le public vous lâche), la meilleure façon d’y parvenir est d’en faire une œuvre libre que chacun peut redistribuer et changer suivant ces termes-ci.
61 |
62 | Pour appliquer ces termes, attachez les notices suivantes à l'œuvre. Il est plus sûr de les attacher au début de chacun des fichiers sources afin de transporter de façon la plus effective possible l’exclusion de garantie ; et chaque fichier devrait comporter au moins la ligne de réservation de droit («copyright») et une indication permettant de savoir où la notice complète peut être trouvée :
63 |
64 |
65 | Copyright (C) — Tous droits réservés.
66 |
67 | Cette œuvre est distribuée SANS AUCUNE GARANTIE hormis celle d'être distribuée
68 | sous les termes de la Licence Demerdez-vous («Demerden Sie Sich License»)
69 | telle que publiée par Flyounet : soit la version 1 de cette licence,
70 | soit (à votre gré) toute version ultérieure.
71 |
72 | Vous devriez avoir reçu une copie de la Licence Démerdez-vous avec cette
73 | œuvre ; si ce n’est pas le cas, consultez :
74 | .
75 |
76 |
77 |
78 | ##############################################################################
79 |
--------------------------------------------------------------------------------
/scripts/bmflyounet_to_bm060.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | originalBM="${HOME}/bm.lnk"
5 | backBM="${HOME}/bm.lnk.before060"
6 |
7 | die() { echo "${@}"; exit 1; }
8 |
9 | [[ ! -f "${originalBM}" ]] && die "Please update this script to to tell where is your current bookmark. Aborting."
10 | [[ -f "${backBM}" ]] && die "A file already exist with this name ${backBM} (remove the file or edit the script). Aborintg."
11 |
12 | cp -f -- "${originalBM}" "${backBM}" || die "Unable to backup your bookmarks fie. Aborting."
13 |
14 | awk -F'|' 'BEGIN {OFS="|";} {$1=$1 "|" $NF; $NF=""; print $0;}' "${backBM}" | sed -e 's;|$;;' > "${originalBM}"
15 |
16 | echo "Export done for ${originalBM} (backup is ${backBM}). You should execute: bm -S"
17 |
--------------------------------------------------------------------------------
/scripts/bmtj_to_bm060.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | originalBM="${HOME}/Dropbox/bookmarks"
5 | newBM="${HOME}/bm.lnk"
6 |
7 | die() { echo "${@}"; exit 1; }
8 |
9 | [[ ! -f "${originalBM}" ]] && die "Please update this script to to tell where is your old bookmark. Aborting."
10 | [[ -f "${newBM}" ]] && die "A file already exist with this name ${newBM} (remove the file or edit the script). Aborintg."
11 |
12 | [[ $(awk -F'|' '(NF > 3) { print $0;exit 2; }' "${originalBM}") -ne 0 ]] && die "Either your old file is not readable or some lines have more than 3 fields"
13 |
14 | A=0
15 | IFS='|'
16 | while read u T t; do
17 | m="$(md5sum <<< "${u}")"
18 | d="$(date "+%FT%TZ")"
19 | ((A++))
20 | echo "${m%% *}|${d}|:${A}|${u}|${T}|${t//[ ]/,}" >> "${newBM}"
21 | done < "${originalBM}"
22 |
23 | echo "Export done from ${originalBM} to ${newBM}. You should execute: bm -S"
24 |
--------------------------------------------------------------------------------