def refresh_posts(if_older_than=timedelta(minutes=30), force=False):
    global cache
    global pbutil_verbose
    if cache_path.exists():
        cache = pickle.load(open(cache_path, 'rb'))
    else:
        cache = {'posts': [], 'last_updated': None}
        pickle.dump(cache, open(cache_path, 'wb'))

    if not cache['posts'] or (datetime.now() -
                              cache['last_updated']) > if_older_than or force:
        if pbutil_verbose:
            print("REFRESHING POSTS")
        token = Path("~/.pinboard").expanduser().read_text().strip()
        pb = pinboard.Pinboard(token)
        cache['posts'] = pb.posts.all()
        cache['last_updated'] = datetime.now()
        if pbutil_verbose:
            print("New post refresh threshold:",
                  cache['last_updated'].strftime("%H:%M"))
        pickle.dump(cache, open(cache_path, 'wb'))
    else:
        if pbutil_verbose:
            print("USING `OLD` POSTS TILL",
                  (cache['last_updated'] + if_older_than).strftime("%H:%M"))
def run_options(args):
    """
    Run functions that the user has specified
    """
    pb = pinboard.Pinboard(args.pinboard_token)

    if args.version:
        print(__version__)
        return
    if args.func in ["github"]:
        print("Saving Github stars to Pinboard...")
        save_git_stars(pb, args.token)
    elif args.func in ["reddit"]:
        print("Saving Reddit saved links to Pinboard...")
        save_reddit_links(pb, args.username, args.password, args.secret,
                          args.client_id)
    elif args.func in ["tags"]:
        pin_tags(pb, args.config)
    elif args.func in ["titles"]:
        if not args.tag:
            print("Please specify a tag to fix titles for")
            return
        fix_titles(pb, args.tag)
    else:
        print("No argument specified, use -h for help")
Exemple #3
0
 def get_items(self):
     token = __kupfer_settings__["token"]
     if token == "":
         return []
     pb = pinboard.Pinboard(token)
     bookmarks = pb.posts.all(start=0, results=100)
     return [UrlLeaf(b.url, b.description) for b in bookmarks]
Exemple #4
0
def get_recent_unread(api_key, tags=["kindle"]):
    pb = pinboard.Pinboard(api_key)
    bookmarks = pb.posts.recent(count=50, tag=tags)

    posts = []
    for bm in bookmarks.get('posts'):
        if bm.toread:
            posts.append(bm.url)
    return posts
def unshare_all_posts(dry_run=True):
    """Make all posts unshared"""
    api_token = get_api_token()
    pb = pinboard.Pinboard(api_token)
    shared_posts = list(filter(lambda p: p.shared, pb.posts.all()))
    for post in tqdm.tqdm(shared_posts):
        if post.share:
            post.shared = False
            if not dry_run:
                post.save()
def getAllPosts(apiToken):
    pb = pinboard.Pinboard(apiToken)

    try:
        posts = pb.posts.all()
    except:
        click.echo("Error getting bookmarks from Pinboard")
        sys.exit(-1)
    else:
        #return json.load(posts)
        return posts
Exemple #7
0
def main:
    api_token = os.environ['PINBOARD_API_TOKEN']
    
    pb = pinboard.Pinboard(api_token)

    yesterday = datetime.datetime.now() - datetime.timedelta(days=1)
    recent_bookmarks = pb.posts.all(results=100, fromdt=yesterday)["posts"]

    youtube_bookmarks = [x for x in recent_bookmarks if is_youtube_url(x.url)]

    for bookmark in youtube_bookmarks:
        download_and_backup(bookmark)
Exemple #8
0
 def __init__(self,
              api_key,
              filters=None,
              private_only=False,
              public_only=False,
              toread_only=False,
              read_only=False):
     self.buku = buku.BukuDb()
     self.pb = pinboard.Pinboard(api_key)
     self.filters = filters
     self.private_only = private_only
     self.public_only = public_only
     self.toread_only = toread_only
     self.read_only = read_only
Exemple #9
0
    def __init__(self):

        logging.basicConfig(
            format='%(asctime)s \t %(levelname)s \t %(message)s',
            level=logging.DEBUG)

        self.settings = yaml.safe_load(open('settings.yml'))

        self.r = praw.Reddit(
            username=self.settings['reddit']['username'],
            password=self.settings['reddit']['password'],
            client_id=self.settings['reddit']['client_id'],
            client_secret=self.settings['reddit']['client_secret'],
            user_agent=self.settings['reddit']['user_agent'])

        self.pb = pinboard.Pinboard(self.settings['pinboard']['apikey'])
        self.gh = github3.login(self.settings['github']['username'],
                                self.settings['github']['password'])
        self.ttrss = TTRClient(self.settings['ttrss']['url'],
                               self.settings['ttrss']['username'],
                               self.settings['ttrss']['password']).login()
    def handle(self, *args, **kwargs):

        # Compare the last time we saved a bookmark locally to the latest update
        # pinboard has on the server. This isn't exactly the same since pinboard's
        # update stamp also includes edits and deletions, but I so rarely actually
        # edit/delete bookmarks that I don't really care enough to fix that
        # discrepancy at this time.

        latest_blogmark = (Blogmark.objects.filter(
            import_ref__startswith="pinboard:").values("created").latest(
                "created"))
        latest_blogmark_timestamp = latest_blogmark["created"]
        pb = pinboard.Pinboard(settings.PINBOARD_API_KEY)
        latest_pinboard_update = pb.posts.update().replace(tzinfo=utc)
        if latest_pinboard_update <= latest_blogmark_timestamp:
            print(f"no updates since {latest_blogmark_timestamp}",
                  file=self.stdout)
            return

        for bookmark in pb.posts.all(fromdt=latest_blogmark_timestamp, meta=1):
            if not bookmark.shared:
                print(f"{bookmark.url} is private; skipping")
                continue

            blogmark, created = Blogmark.objects.update_or_create(
                import_ref=f"pinboard:{bookmark.hash}",
                defaults={
                    "slug": slugify(bookmark.description),
                    "link_url": bookmark.url,
                    "link_title": bookmark.description,
                    "commentary": bookmark.extended,
                    "created": bookmark.time.replace(tzinfo=utc),
                    "metadata": {
                        "pinboard_meta": bookmark.meta
                    },
                },
            )
            blogmark.tags.set(
                Tag.objects.get_or_create(tag=tag)[0] for tag in bookmark.tags)
            print("created" if created else "updated", blogmark.link_url)
Exemple #11
0
def cli(ctx, save, apikey):

    if apikey:
        apikey = apikey[0]
    else:
        apikey = None

    if apikey is None:
        apikey = os.environ.get('RANDPIN_APIKEY')

    if apikey is None:

        configpath = get_config_path()

        if not configpath.exists():
            raise click.ClickException("Couldn't find the API key")

        with configpath.open('r') as f:
            apikey = f.read().strip()

        if not apikey:
            raise click.ClickException(
                "Wasn't able to load API key. Try saving again.")

    if save:
        with get_config_path().open('w') as f:
            print(apikey, file=f)

    pb = pinboard.Pinboard(apikey)

    unread = [b for b in pb.posts.all() if b.toread]
    random_unread = random.choice(unread)

    click.echo("Opening: {}".format(random_unread.url))
    returncode = click.launch(random_unread.url)

    ctx.exit(returncode)
Exemple #12
0
def main(api_token, y=None, m=None):
    today = date.today()
    year = y if y is not None else today.year
    month = m if m is not None else today.month
    day = calendar.monthrange(
        year, month)[1] if (y is not None and m is not None) else today.day
    print('''---
title: Links for the month of %s
---''' % (date(year, month, 1).strftime('%B %Y'), ))
    for i in range(1, day + 1):
        nenne = date(year, month, i)
        pb = pinboard.Pinboard(api_token)
        posts = pb.posts.get(dt=nenne)
        shared = [post for post in posts['posts'] if post.shared]
        if not posts.get('posts'):
            sys.exit(0)
        elif len(shared) > 0:
            print('\n**%s:**\n' % (nenne.strftime('%A, %B %d %Y'), ))
        for post in shared:
            print('* [%s](%s)' %
                  (post.description.encode('utf-8'), post.url.encode('utf-8')))
            # //pinboard.in/u:%s/b:%s = (user, post.hash[:12].encode('utf-8'))
            if post.extended:
                print('-- %s' % (post.extended.decode('utf-8'), ))
Exemple #13
0
 def __init__(self, api_key, filters=None, toread_only=False):
     self.buku = buku.BukuDb()
     self.pb = pinboard.Pinboard(api_key)
     self.filters = filters
     self.toread_only = toread_only
Exemple #14
0
#!/usr/bin/python

import pinboard
from datetime import datetime
from dateutil import tz
from slugify import slugify
import os
from urlparse import urlparse, parse_qsl

pb = pinboard.Pinboard(os.environ['PINBOARD_API'])


def make_post(p, timestamp):

    post_template = u"""---
title: "{}"
slug: {}
date: {}
category: {}
external-url: {}
hash: {}
year: {}
month: {}
scheme: {}
host: {}
path: {}
{}
---

{}
"""
Exemple #15
0
import credentials
import pinboard

api_token = credentials.login['token']
pb = pinboard.Pinboard(api_token)

# Don't know why this library returns a map for recent() and a list for all()
# wikimarks = pb.posts.recent(tag=["wikipedia"])
# print(wikimarks['posts'][0].url)

# output_file = open('wikipedia.txt', 'w')

# for wikimark in wikimarks['posts']:
# 	output_file.write("%s\n" % wikimark.url)

# output_file.close()

wikimarks = pb.posts.all(tag=["wikipedia"])
# print(wikimarks)

output_file = open('wikipedia.txt', 'w')

for wikimark in wikimarks:
    output_file.write("%s\n" % wikimark.url)

output_file.close()
import pinboard
import datetime
from docx import Document
from docx.shared import Inches
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.lib.enums import TA_JUSTIFY

pb = pinboard.Pinboard('lsanz_observatorio:CC8E7F9E71CC9B935378')


def escribir_resumen_semanal():
    posts = pb.posts.recent(tag=["pw"])
    print(posts)
    lista_contenido_descripcion = list()
    lista_contenido_url = list()
    with open(
            "Resumenes Semanales/resumen_semanal{}.txt".format(
                datetime.datetime.now()), "w") as resumen_semanal_file:
        for post in posts["posts"]:
            resumen_semanal_file.write(post.description + "\n")
            resumen_semanal_file.write(post.url + "\n \n")
            lista_contenido_descripcion.append(post.description)
            lista_contenido_url.append(post.url)
    escribir_docx(lista_contenido_descripcion, lista_contenido_url)
    escribir_html("Resumen Semanal", lista_contenido_descripcion,
                  lista_contenido_url)

 def __init__(self, pinboard_token, start=0, count=20):
     self.pinboard_token = pinboard_token
     self.pinboard = pinboard.Pinboard(pinboard_token)
     self.count = count
     self.start = start
"""Example on how to use pinboard api using your api key and tag."""
# Note, get your api token at https://pinboard.in/settings/password
# Set the token in a configs.py file that you set pinapi = "your token"
import pinboard
from configs import pinapi
import datetime

one_day_ago = datetime.datetime.now() - datetime.timedelta(days=1)
pb = pinboard.Pinboard(pinapi)  # set to your api here username:api
sec = pb.posts.all(tag=["wrk"], results=10, fromdt=one_day_ago)
for key in sec:
    print(key.description, key.tags, key.url, key.extended)
Exemple #19
0
from typing import Dict, List, Union

import pinboard
from nebooman import Manager

pinboard_key = ""

pb = pinboard.Pinboard(pinboard_key)

tags: List = pb.tags.get()
tags.sort(key=lambda t: len(t.name))  # sort by length

print("tags: {}".format(tags))

bookmarks = []


def get_key(parent: Union[Dict, List], key: str):
    """simulate `dict.get()` on list"""
    if isinstance(parent, dict):
        lst = parent["children"]
    else:
        lst = parent

    for each in lst:
        if each["title"] == key and "href" not in each:
            return each

    item = {"title": key, "children": []}
    print("Create parent folder {}".format(key))
Exemple #20
0
def main():
    # Load the configuration file and determine default values for a
    # few parameters.
    config_name = os.path.expanduser('~/.pocket2pinboardrc')
    cfg = config.read(config_name)
    since = cfg.get('history', 'since')
    pinboard_token = cfg.get('pinboard', 'token')
    pocket_token = cfg.get('pocket', 'token')
    if not pinboard_token:
        # Save the skeleton file to make editing it easier later.
        config.save(cfg, config_name)

    # Handle command line arguments.
    parser = argparse.ArgumentParser()
    dist = pkg_resources.get_distribution('pocket2pinboard')
    parser.add_argument(
        '--version',
        action='version',
        version='%(prog)s {0}'.format(dist.version),
    )
    parser.add_argument(
        '-v',
        dest='verbose',
        action='store_true',
        default=False,
        help='provide verbose output',
    )
    parser.add_argument(
        '--all',
        action='store_true',
        default=False,
        help='process all pocket articles',
    )
    parser.add_argument(
        '--pinboard-token',
        '-t',
        default=pinboard_token,
        help='pinboard.in API token',
    )
    args = parser.parse_args()

    # Make sure we know how to talk to pinboard.in.
    if not args.pinboard_token:
        parser.error(
            'Please update the pinboard token in %s or provide one via -t' %
            config_name)

    # Set up logging for use as output channel.
    level = logging.DEBUG if args.verbose else logging.INFO
    logging.basicConfig(
        level=level,
        format='%(message)s',
    )
    if not args.verbose:
        requests_logger = logging.getLogger('requests')
        requests_logger.setLevel(logging.WARNING)

    try:
        # Connect to both services early to find authentication
        # issues.
        if not pocket_token:
            pocket_token = pocket.authenticate()
            cfg.set('pocket', 'token', pocket_token)
            config.save(cfg, config_name)
        pinboard_client = pinboard.Pinboard(args.pinboard_token)

        # Get a list of the pocket items we are going to process.
        if args.all:
            since = None
        if since:
            LOG.info('loading pocket items since %s',
                     datetime.datetime.fromtimestamp(float(since)))
        else:
            LOG.info('fetching all pocket items')

        items, new_since = pocket.get_items(
            pocket_token,
            since,
        )

        # Send the pocket items to pinboard.
        bookmarks.update(pinboard_client, items)

        # Remember the new value for 'since'.
        cfg.set('history', 'since', str(new_since))
        config.save(cfg, config_name)
    except Exception as e:
        if args.verbose:
            raise
        parser.error(e)
        sys.exit(1)
def list_all_posts():
    """List all posts"""
    api_token = get_api_token()
    pb = pinboard.Pinboard(api_token)
    for post in pb.posts.all():
        print(get_post_json(post))
Exemple #22
0
__license__ = "Unlicense"

import secret

import argparse
import logging
import ssl
import sys

from bs4 import BeautifulSoup
import pinboard
import requests

TAG_TO_ADD = '.n'

pb = pinboard.Pinboard(secret.token)


def get_html(b):
    try:
        request = requests.get(b.url)
        request.raise_for_status()
        return BeautifulSoup(request.text, 'html.parser')
    except Exception as e:
        try:
            logging.debug('Retrieving %s as a browser' % b.url)
            request = requests.get(
                b.url,
                headers={
                    'User-Agent':
                    'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14',
Exemple #23
0
    def __init__(self, exportType):

        self.postedCount = 0
        self.exportType = exportType

        if self.exportType == 'pb':
            import pinboard
            self.pb = pinboard.Pinboard(PINBOARD_API_KEY)

        converted = subprocess.call(
            ['plutil', '-convert', 'xml1', bookmarksFileCopy])

        if converted != 0:
            print 'Couldn\'t convert bookmarks plist from xml format'
            sys.exit(converted)

        plist = plistlib.readPlist(bookmarksFileCopy)
        # There should only be one Reading List item, so take the first one
        readingList = [
            item for item in plist['Children']
            if 'Title' in item and item['Title'] == 'com.apple.ReadingList'
        ][0]

        if self.exportType == 'pb':
            lastRLBookmark = self.pb.posts.recent(tag='.readinglist', count=1)
            last = lastRLBookmark['date']
        else:
            self.content = ''
            self.newcontent = ''
            # last = time.strptime((datetime.now() - timedelta(days = 1)).strftime('%c'))
            last = time.strptime("2013-01-01 00:00:00 UTC",
                                 '%Y-%m-%d %H:%M:%S UTC')

            if not os.path.exists(markdownFile):
                open(markdownFile, 'a').close()
            else:
                with open(markdownFile, 'r') as mdInput:
                    self.content = mdInput.read()
                    matchLast = re.search(
                        re.compile(
                            '(?m)^Updated: (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} UTC)'
                        ), self.content)
                    if matchLast != None:
                        last = time.strptime(matchLast.group(1),
                                             '%Y-%m-%d %H:%M:%S UTC')

            last = datetime(*last[:6])

            rx = re.compile(
                "(?m)^Updated: (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) UTC")
            self.content = re.sub(rx, '', self.content).strip()

        if 'Children' in readingList:
            cleanRx = re.compile("[\|\`\:_\*\n]")
            for item in readingList['Children']:
                if item['ReadingList']['DateAdded'] > last:
                    addtime = pytz.utc.localize(
                        item['ReadingList']['DateAdded']).strftime('%c')
                    title = re.sub(
                        cleanRx, ' ',
                        item['URIDictionary']['title'].encode('utf8'))
                    title = re.sub(' +', ' ', title)
                    url = item['URLString']
                    description = ''

                    if 'PreviewText' in item['ReadingList']:
                        description = item['ReadingList'][
                            'PreviewText'].encode('utf8')
                        description = re.sub(cleanRx, ' ', description)
                        description = re.sub(' +', ' ', description)

                    if self.exportType == 'md':
                        self.itemToMarkdown(addtime, title, url, description)
                    else:
                        self.itemToPinboard(title, url, description)
                else:
                    break

        pluralized = 'bookmarks' if self.postedCount > 1 else 'bookmark'
        if self.exportType == 'pb':
            if self.postedCount > 0:
                sys.stdout.write('Added ' + str(self.postedCount) + ' new ' +
                                 pluralized + ' to Pinboard')
            else:
                sys.stdout.write('No new bookmarks found in Reading List')
        else:
            mdHandle = open(markdownFile, 'w')
            mdHandle.write('Updated: ' +
                           datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') +
                           " UTC\n\n")
            mdHandle.write(self.newcontent + self.content)
            mdHandle.close()
            if self.postedCount > 0:
                sys.stdout.write('Added ' + str(self.postedCount) + ' new ' +
                                 pluralized + ' to ' + markdownFile)
            else:
                sys.stdout.write('No new bookmarks found in Reading List')

        sys.stdout.write("\n")
Exemple #24
0
def main():
    token = Path("~/.pinboard").expanduser().read_text().strip()
    pb = pinboard.Pinboard(token)

    tag_to_find = sys.argv[1]
    posts = pb.posts.all(tag=tag_to_find)

    g2 = nx.Graph()
    for bookmark in posts:
        for tag in bookmark.tags:
            g2.add_node(tag)
            for other_tag in bookmark.tags:
                if tag == other_tag:
                    continue
                if other_tag not in g2:
                    g2.add_node(other_tag)
                if other_tag in g2[tag]:
                    g2[tag][other_tag]['weight'] += 1
                else:
                    g2.add_edge(tag, other_tag, weight=1)

    width = np.log(len(g2)) * 10
    height = width
    if len(g2) == 1:
        width = height = 4
    f, ax = plt.subplots(1, figsize=(width, height))

    pos = nx.drawing.spring_layout(g2,
                                   scale=2,
                                   k=1.5 / np.sqrt(len(g2)),
                                   iterations=500)
    nx.draw_networkx_nodes(g2, pos, node_size=10000, ax=ax)

    weights = set(d['weight'] for (_, _, d) in g2.edges(data=True))
    for weight in weights:
        edgelist = [(u, v) for (u, v, d) in g2.edges(data=True)
                    if d['weight'] == weight]
        nx.draw_networkx_edges(g2,
                               pos,
                               edgelist=edgelist,
                               width=np.log(weight) * 3,
                               ax=ax)

    labels = [f'{n}\n{label_sum(g2, n)}' for n in g2.nodes]
    edgelabels = dict(zip(g2, labels))
    nx.draw_networkx_labels(g2,
                            pos,
                            labels=edgelabels,
                            font_size=20,
                            font_family='sans-serif',
                            ax=ax)
    plt.axis('off')
    plt.show()
    f.savefig(f"pbtg_{tag_to_find}.svg",
              dpi=10000,
              facecolor='w',
              edgecolor='w',
              orientation='portrait',
              papertype=None,
              format=None,
              transparent=False,
              bbox_inches=None,
              pad_inches=0.1)
Exemple #25
0
def main(api_token,
         tags,
         from_date,
         to_date=datetime.date.today(),
         no_random_cover_image=False,
         no_credit=False):
    username, key = api_token.split(':')

    days = (to_date - from_date).days
    if days < 0:
        print('Invalid date range', file=sys.stderr)
        sys.exit(1)

    pb = pinboard.Pinboard(api_token)
    unique_posts = {}
    for tag in tags:
        posts = pb.posts.all(tag=tag, results=100, fromdt=from_date)
        for post in posts:
            unique_posts.update({post.url: post})
    posts = unique_posts.values()

    if not posts:
        print('No articles found!', file=sys.stderr)
        sys.exit(1)

    print('''# ICYMI 웹 탐험 – %s''' % (to_date.strftime('%Y년 %m월 %d일')))
    print('')

    if not no_random_cover_image:
        r = requests.get('https://unsplash.it/1920/1080/?random')
        print('![]({})'.format(r.url))
        print('')

    if not no_credit:
        print(
            '''> 이 글은 [GitHub - andromedarabbit/pinlinks: Generate a markdown blog post from recent pinboard bookmarks](https://github.com/andromedarabbit/pinlinks)로 자동생성하였습니다'''
        )
        print('')

    print('''**기간**: %s ~ %s''' % (from_date.isoformat(), to_date.isoformat()))
    print('')

    # re_blockquotes = re.compile(r'^(\s+>|>)\s+(.*)$', re.MULTILINE)

    # Not note
    pure_posts = [
        post for post in posts
        if not post.url.startswith('https://notes.pinboard.in/u:' + username)
    ]

    for post in pure_posts:
        if not post.description:
            continue

        print('* **[%s](%s)**' % (post.description, post.url))

        if post.extended:
            desc = get_desc(post.extended, True)
            print('%s' % (desc, ))

    # Note only
    note_posts = [
        post for post in posts
        if post.url.startswith('https://notes.pinboard.in/u:' + username)
    ]

    if note_posts:
        print('')
        print('''## 메모''')
        print('')

    for post in note_posts:
        note_id = post.url.replace(
            'https://notes.pinboard.in/u:' + username + '/', '')

        try:
            fun = pb.notes[note_id]
            response = fun(parse_response=False)
        except pinboard.PinboardServerError as e:
            print("HTTP Error 500: Internal Server Error. Either you have " \
                    "provided invalid credentials or the Pinboard API " \
                    "encountered an internal exception while fulfilling " \
                    "the request.")

            raise e
        else:
            json_response = json.load(response)

            title = json_response['title'] if json_response[
                'title'] else "NO TITLE"
            text = json_response['text']

            print('### [%s](%s)' % (title, post.url))
            print('')

            if text:
                desc = get_desc(text)
                print('%s' % (desc, ))

    print('')
Exemple #26
0
import feedbin
import pinboard

feedbin_email = ''
feedbin_password = ''  # base64 encode your password
pinboard_api_token = ''  # base64 encode your api token

fb = feedbin.Feedbin(feedbin_email, feedbin_password)
pb = pinboard.Pinboard(pinboard_api_token)

fb.parse_stars()

for bookmark in fb.to_boomark:
    pb.add_post(bookmark)

fb.write_cache_data()
Exemple #27
0
 def __init__(self):
     self.api = pinboard.Pinboard(PINBOARD_API_TOKEN)
     self.user = PINBOARD_API_TOKEN.split(':')[0]
     self.base_url = BASE_SERVICE_URL
import os
from dotenv import load_dotenv, find_dotenv, set_key
load_dotenv()

from dateutil.parser import parse

import pandas as pd
import json
import string

import pinboard

import secrets as se

pk = se.pinboard_key
pb = pinboard.Pinboard(pk)

out = pb.posts.all(parse_response=False)
out = json.loads(out.read().decode("utf-8"))

# pull last import date from .env file
pinboard_last_pull = os.getenv('pinboard_last_pull')
print("pinboard last date pulled: ", pinboard_last_pull)

# if None, set to 1990
if pinboard_last_pull is None:
    pinboard_last_pull = "1990-01-01"

# filter bookmarks based on last pulled date
out = [i for i in out if parse(i['time'][:10]) >= parse(pinboard_last_pull)]
print("new notes: ", len(out))
    def __init__(self, exportType):

        self.postedCount = 0
        self.exportType = exportType

        timestamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")

        if self.exportType == 'pb':
            print("%s: Exporting bookmarks to Pinboard" % timestamp)
        elif self.exportType == 'md':
            print("%s: Exporting bookmarks to Markdown file %s" %
                  (timestamp, BOOKMARKS_MARKDOWN_FILE))
        else:
            print("%s: Exporting bookmarks with exportType %s" %
                  (timestamp, self.exportType))

        if self.exportType == 'pb':
            import pinboard
            self.pb = pinboard.Pinboard(PINBOARD_API_KEY)

        with open(bookmarksFileCopy, 'rb') as fp:
            plist = plistlib.load(fp)

        # There should only be one Reading List item, so take the first one
        readingList = [
            item for item in plist['Children']
            if 'Title' in item and item['Title'] == 'com.apple.ReadingList'
        ][0]

        # Determine last synced bookmark
        if self.exportType == 'pb':
            # For Pinboard, use the last synced bookmark OR start from 2013-01-01 if no synced bookmarks
            lastRLBookmark = self.pb.posts.recent(tag='.readinglist', count=1)
            if len(lastRLBookmark['posts']) > 0:
                last = lastRLBookmark['date']
            else:
                last = datetime.strptime("2013-01-01 00:00:00 UTC",
                                         '%Y-%m-%d %H:%M:%S UTC')
        else:
            # For Markdown, get the markdown file (if it exists) and pull the updated time from the header of that file
            # Fall back to 2013-01-01 if not found.
            self.content = ''
            self.newcontent = ''
            # last = time.strptime((datetime.now() - timedelta(days = 1)).strftime('%c'))
            last = time.strptime("2013-01-01 00:00:00 UTC",
                                 '%Y-%m-%d %H:%M:%S UTC')

            if not os.path.exists(markdownFile):
                open(markdownFile, 'a').close()
            else:
                with open(markdownFile, 'r') as mdInput:
                    self.content = mdInput.read()
                    matchLast = re.search(
                        re.compile(
                            '(?m)^Updated: (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} UTC)'
                        ), self.content)
                    if matchLast != None:
                        last = time.strptime(matchLast.group(1),
                                             '%Y-%m-%d %H:%M:%S UTC')

            last = datetime(*last[:6])

            rx = re.compile(
                "(?m)^Updated: (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) UTC")
            self.content = re.sub(rx, '', self.content).strip()

        # Process new bookmarks in Reading List
        if 'Children' in readingList:
            cleanRx = re.compile("[\|\`\:_\*\n]")
            for item in readingList['Children']:
                if item['ReadingList']['DateAdded'] > last:
                    addtime = pytz.utc.localize(
                        item['ReadingList']['DateAdded']).strftime('%c')
                    #print(item['URIDictionary']['title'])
                    title = re.sub(cleanRx, ' ',
                                   item['URIDictionary']['title'])
                    title = re.sub(' +', ' ', title)
                    url = item['URLString']
                    description = ''

                    if 'PreviewText' in item['ReadingList']:
                        description = item['ReadingList']['PreviewText']
                        description = re.sub(cleanRx, ' ', description)
                        description = re.sub(' +', ' ', description)

                    if self.exportType == 'md':
                        self.itemToMarkdown(addtime, title, url, description)
                    else:
                        if not title.strip():
                            title = 'no title'
                        post_time = pytz.utc.localize(
                            item['ReadingList']['DateAdded'])
                        self.itemToPinboard(post_time, title, url, description)
                else:
                    break

        # Write output logging information
        pluralized = 'bookmarks' if self.postedCount > 1 else 'bookmark'

        if self.exportType == 'pb':
            if self.postedCount > 0:
                sys.stdout.write('Added ' + str(self.postedCount) + ' new ' +
                                 pluralized + ' to Pinboard')
            else:
                sys.stdout.write('No new bookmarks found in Reading List')
        else:
            mdHandle = open(markdownFile, 'w')
            mdHandle.write('Updated: ' +
                           datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S') +
                           " UTC\n\n")
            mdHandle.write(self.newcontent + self.content)
            mdHandle.close()
            if self.postedCount > 0:
                sys.stdout.write('Added ' + str(self.postedCount) + ' new ' +
                                 pluralized + ' to ' + markdownFile)
            else:
                sys.stdout.write('No new bookmarks found in Reading List')

        sys.stdout.write("\n")