all repos — nasg @ b5eb93cd8ca6040d468d80d4da1d208549a5fa4c

adding last.fm to archiver
Peter Molnar hello@petermolnar.eu
Wed, 01 Nov 2017 13:19:39 +0000
commit

b5eb93cd8ca6040d468d80d4da1d208549a5fa4c

parent

3bef504be152149be1f331528aee9b8763b84221

5 files changed, 153 insertions(+), 23 deletions(-)

jump to
M archive.pyarchive.py

@@ -7,6 +7,7 @@ import shutil

import subprocess import imghdr import arrow +import csv from requests_oauthlib import OAuth1Session from requests_oauthlib import oauth1_session

@@ -15,6 +16,86 @@ from requests_oauthlib import oauth2_session

from oauthlib.oauth2 import BackendApplicationClient import shared + +class LastFM(object): + url = 'http://ws.audioscrobbler.com/2.0/' + def __init__(self): + self.service = 'lastfm' + self.target = shared.config.get("api_%s" % self.service, 'logfile') + self.params = { + 'method': 'user.getrecenttracks', + 'user': shared.config.get("api_%s" % self.service, 'username'), + 'api_key': shared.config.get("api_%s" % self.service, 'api_key'), + 'format': 'json', + 'limit': '200' + } + if os.path.isfile(self.target): + mtime = os.path.getmtime(self.target) + self.params.update({'from': mtime}) + + def hash2flat(self, data): + time = int(data.get('date').get('uts')) + r = { + 'date': arrow.get(time).format(shared.ARROWFORMAT['iso']), + 'title': data.get('name'), + 'title_mbid': data.get('mbid'), + 'artist': data.get('artist').get('#text'), + 'artist_mbid': data.get('artist').get('mbid'), + 'album': data.get('album').get('#text'), + 'album_mbid': data.get('album').get('mbid'), + } + return (time, r) + + def getpaged(self, pagenum): + logging.info('requesting page #%d of paginated results', pagenum) + self.params.update({ + 'page': pagenum + }) + r = requests.get( + self.url, + params=self.params + ) + parsed = json.loads(r.text).get('recenttracks', {}).get('track', []) + return parsed + + def run(self): + r = requests.get(self.url,params=self.params) + js = json.loads(r.text) + js = js.get('recenttracks', {}) + unordered = js.get('track', []) + ordered = {} + + total = int(js.get('@attr').get('totalPages')) + current = int(js.get('@attr').get('page')) + cntr = total - current + + while cntr > 0: + current = current + 1 + paged = self.getpaged(current) + unordered = unordered + paged + cntr = total - current + + for track in unordered: + # happens with nowplaying tracks + if 'date' not in track: + continue + time, data = self.hash2flat(track) + ordered[time] = data + + # no results + if not len(ordered): + return + + ordered = sorted(ordered.items()) + with open(self.target, 'a') as f: + fieldnames = ordered[0][1].keys() + writer = csv.DictWriter(f, fieldnames=fieldnames) + # only write csv header once, when the file is first created + if 'from' not in self.params: + writer.writeheader() + for time, track in ordered: + writer.writerow(track) + class Favs(object): def __init__(self, confgroup):

@@ -865,3 +946,7 @@

if shared.config.has_section('api_deviantart'): da = DAFavs() da.run() + + if shared.config.has_section('api_lastfm'): + lfm = LastFM() + lfm.run()
M nasg.pynasg.py

@@ -892,12 +892,12 @@ if crop:

thumb.liquid_rescale(size, size, 1, 1) if self.meta.get('FileType', 'jpeg').lower() == 'jpeg': - thumb.compression_quality = 86 + thumb.compression_quality = 94 thumb.unsharp_mask( - radius=0, + radius=2, sigma=0.5, - amount=1, - threshold=0.03 + amount=0.7, + threshold=0 ) thumb.format = 'pjpeg'
M templates/Singular.htmltemplates/Singular.html

@@ -60,6 +60,26 @@ {% endif %}

</p> </footer> + <aside class="donation"> + <p> + {% if post.category == 'photo' %} + Did you like this photo?<br />Thank it with a small donation. + {% elif post.category == 'article' %} + Did you find this article useful?<br />Buy me a coffee, so I can write more like this.<br />If you want my help with something similar, get in touch. + {% elif post.category == 'journal' %} + Did you like this entry?<br />Encourage me to write more of them. + {% else %} + Did you like what you read?<br />Thank it with a small donation.</a> + {% endif %} + </p> + <ul> + {% for value in [3,5,10,42] %} + <li><a href="{{ site.author.donateurl }}{{value}}GBP">£{{value}}</a></li> + {% endfor %} + </ul> + </aside> + + {% if post.replies|length %} <section class="replies"> <h6><a name="replies"></a>Replies</h6>
M templates/block_footer.htmltemplates/block_footer.html

@@ -1,11 +1,10 @@

<footer class="content-footer" id="main-footer"> <nav class="footer-contact p-author h-card vcard limit"> - <img class="photo avatar u-photo u-avatar" src="{{ site.author.avatar }}" alt="Photo of {{ site.author.name }}" /> <dl> - <dt>name</dt> <dd> + <img class="photo avatar u-photo u-avatar" src="{{ site.author.avatar }}" alt="Photo of {{ site.author.name }}" /> <a class="fn p-name url u-url u-uid" href="{{ site.author.url }}/about">{{ site.author.name }}</a> </dd> <dt>email</dt>
M templates/style-dark.csstemplates/style-dark.css

@@ -145,35 +145,26 @@

code, pre { font-family: "Inconsolata", "Courier New", monospace; - font-size: 0.9rem; + font-size: 0.8rem; color: limegreen; + background-color: #222; + border: 1px solid #666; direction: ltr; text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; tab-size: 2; - hyphens: none; - outline: 1px solid #666; - background-color: #222; } -pre { +pre { + overflow: auto; padding: 0.3rem; - margin: 0.6rem 0; - overflow: auto; } code { - display: inline-block; - padding: 0 0.3rem 0.1rem 0.3rem; - line-height: 0.9rem; + padding: 0.1rem; } pre code { - background-color: transparent; border: none; - padding: 0; } code.sourceCode span.al { color: limegreen; }

@@ -198,6 +189,7 @@ code.sourceCode span.sc { color: limegreen; }

code.sourceCode span.ss { color: limegreen; } code.sourceCode span.st { color: magenta; } code.sourceCode span.va { color: turquoise; } + .limit, .content-body {

@@ -318,11 +310,16 @@ .content-footer {

margin-top: 2rem; padding: 0.3rem 0; opacity: 0.8; + text-align: center; +} + +.content-footer * { + display: inline-block; + vertical-align: top; } .content-footer img { - width: 1.1rem; - float: left; + width: 1rem; margin: 0 0.3rem 0rem 0; }

@@ -570,7 +567,35 @@ padding: 0;

margin: 0 1rem 0 0; } +.donation { + text-align: center; +} +.donation p { + color: #ccc; +} + +.donation ul { + list-style-type: none; + padding: 0 0 1rem 0; +} + +.donation li { + display: inline; +} + +.donation li a { + display: inline-block; + border: 1px dashed #933; + padding: 0.6rem; + background-color: #111; + width: 5rem; +} + +.donation li a:hover { + border: 1px solid #933; + color: #fff; +} /* above is mobile first; this is the desktop */ @media all and (min-width: 50rem) {

@@ -683,6 +708,7 @@ code.sourceCode span.ss { color: black; }

code.sourceCode span.st { color: magenta; } code.sourceCode span.va { color: darkturquoise; } } +