Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 5b743b5

Browse filesBrowse files
committed
short.py now reads files and stdin
1 parent 648e9f6 commit 5b743b5
Copy full SHA for 5b743b5

File tree

3 files changed

+82
-17
lines changed
Filter options

3 files changed

+82
-17
lines changed

‎links/sample-urls.txt

Copy file name to clipboard
+47Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
https://www.oreilly.com/library/view/fluent-python-2nd/9781492056348/
2+
https://dask.org/
3+
http://example.com/1572039572038573208
4+
http://www.unicode.org/
5+
https://www.techcrunch.com/2024/startup-funding-trends
6+
https://blog.medium.com/writing-tips-for-beginners
7+
https://github.com/microsoft/typescript
8+
https://stackoverflow.com/questions/javascript-async-await
9+
https://www.reddit.com/r/programming/hot
10+
https://docs.google.com/spreadsheets/create
11+
https://www.youtube.com/watch?v=dQw4w9WgXcQ
12+
https://www.amazon.com/dp/B08N5WRWNW
13+
https://support.apple.com/iphone-setup-guide
14+
https://www.wikipedia.org/wiki/Machine_Learning
15+
https://www.linkedin.com/in/johndoe123
16+
https://www.instagram.com/p/CxYz123AbC/
17+
https://twitter.com/elonmusk/status/1234567890
18+
https://www.facebook.com/events/987654321
19+
https://drive.google.com/file/d/1AbCdEfGhIjKlMnOp/view
20+
https://www.dropbox.com/s/qwerty123/document.pdf
21+
https://zoom.us/j/1234567890?pwd=abcdef
22+
https://calendly.com/janedoe/30min-meeting
23+
https://www.shopify.com/admin/products/new
24+
https://stripe.com/docs/api/charges/create
25+
https://www.paypal.com/invoice/create
26+
https://mailchimp.com/campaigns/dashboard
27+
https://analytics.google.com/analytics/web/
28+
https://console.aws.amazon.com/s3/buckets
29+
https://portal.azure.com/dashboard
30+
https://www.figma.com/file/AbCdEf123456/design-system
31+
https://www.notion.so/workspace/project-notes
32+
https://trello.com/b/AbCdEfGh/marketing-board
33+
https://slack.com/app_redirect?channel=general
34+
https://discord.gg/AbCdEfGh123
35+
https://www.twitch.tv/streamername/videos
36+
https://www.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M
37+
https://www.netflix.com/browse/genre/83
38+
https://www.hulu.com/series/breaking-bad-2008
39+
https://www.airbnb.com/rooms/12345678
40+
https://www.booking.com/hotel/us/grand-plaza.html
41+
https://www.expedia.com/flights/search?trip=roundtrip
42+
https://www.uber.com/ride/request
43+
https://www.doordash.com/store/pizza-palace-123
44+
https://www.grubhub.com/restaurant/tacos-el-rey-456
45+
https://www.zillow.com/homes/for_sale/San-Francisco-CA
46+
https://www.craigslist.org/about/sites
47+
https://www.python.org/dev/peps/pep-0484/

‎links/short.htaccess

Copy file name to clipboard
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
# file created and managed by short.py
1+
# content of short.htaccess file created and managed by short.py

‎links/short.py

Copy file name to clipboardExpand all lines: links/short.py
+34-16Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
#!/usr/bin/env python3
22

3+
"""
4+
short.py generates unique short URLs.
5+
6+
This script reads lines from stdin or files named as arguments, then:
7+
8+
1. retrieves or creates new short URLs, taking into account existing RedirectTemp
9+
directives in custom.htacess or short.htacess;
10+
2. appends RedirectTemp directives for newly created short URLs to short.htacess;
11+
3. outputs the list of (short, long) URLs retrieved or created.
12+
13+
"""
14+
15+
import fileinput
316
import itertools
417
from collections.abc import Iterator
18+
from time import strftime
519

20+
BASE_DOMAIN = 'fpy.li'
621

722
def load_redirects():
823
redirects = {}
@@ -25,52 +40,55 @@ def load_redirects():
2540
SDIGITS = '23456789abcdefghjkmnpqrstvwxyz'
2641

2742

28-
def gen_short() -> Iterator[str]:
43+
def gen_short(start_len=1) -> Iterator[str]:
2944
"""
30-
Generate every possible sequence of SDIGITS.
45+
Generate every possible sequence of SDIGITS, starting with start_len
3146
"""
32-
length = 1
47+
length = start_len
3348
while True:
3449
for short in itertools.product(SDIGITS, repeat=length):
3550
yield ''.join(short)
3651
length += 1
3752

3853

39-
def gen_free_short(redirects: dict) -> Iterator[str]:
54+
def gen_unused_short(redirects: dict) -> Iterator[str]:
4055
"""
41-
Generate next available short URL.
56+
Generate next available short URL of len >= 2.
4257
"""
43-
for short in gen_short():
58+
for short in gen_short(2):
4459
if short not in redirects:
4560
yield short
4661

4762

4863
def shorten(urls: list[str], redirects: dict, targets: dict) -> list[tuple[str,str]]:
49-
"""return (short, long) pairs, updating short.htaccess as needed""'
50-
iter_short = gen_free_short(redirects)
64+
"""return (short, long) pairs, appending directives to short.htaccess as needed"""
65+
iter_short = gen_unused_short(redirects)
5166
pairs = []
67+
timestamp = strftime('%Y-%m-%d %H:%M:%S')
5268
with open('short.htaccess', 'a') as fp:
5369
for long in urls:
54-
assert 'fpy.li' not in long, f"{long} is a fpy.li URL"
70+
assert BASE_DOMAIN not in long, f"{long} is a {BASE_DOMAIN} URL"
5571
if long in targets:
5672
short = targets[long]
5773
else:
5874
short = next(iter_short)
59-
redirects[short] = url
60-
targets[url] = short
61-
fp.write(f"RedirectTemp /{short} {url}\n")
75+
redirects[short] = long
76+
targets[long] = short
77+
if timestamp:
78+
fp.write(f'\n# appended: {timestamp}\n')
79+
timestamp = None
80+
fp.write(f'RedirectTemp /{short} {long}\n')
6281
pairs.append((short, long))
6382

6483
return pairs
6584

6685

6786
def main():
68-
from random import randrange
69-
urls = [f'https://example.com/{randrange(100000)}.html' for n in range(7)]
70-
87+
"""read URLS from filename arguments or stdin"""
88+
urls = [line.strip() for line in fileinput.input(encoding="utf-8")]
7189
redirects, targets = load_redirects()
7290
for short, long in shorten(urls, redirects, targets):
73-
print(f'fpy.li/{short}\t{long}')
91+
print(f'{BASE_DOMAIN}/{short}\t{long}')
7492

7593

7694
if __name__ == '__main__':

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.