示例#1
0
 def sync_tags(self) -> None:
     """ 同步为知笔记的 tag 到 Joplin Tag
     """
     created_keys = self.cu.tags.keys()
     waiting_create_tags = [
         wt for wt in self.ws.tags
         if not tojoplinid(wt.guid) in created_keys
     ]
     logger.info(f'为知笔记共有 {len(self.ws.tags)} 个 tag 。')
     logger.info(f'有 {len(waiting_create_tags)} 个 tag 等待同步。')
     for wt in waiting_create_tags:
         tag_id = tojoplinid(wt.guid)
         try:
             logger.info(f'处理 tag {wt.name} {tag_id}')
             jt = self.jda.post_tag(id=tag_id,
                                    title=wt.name,
                                    created_time=wt.modified,
                                    updated_time=wt.modified)
             self.cu.add_tag(jt)
         except ValueError as e:
             logger.error(e)
             # 由于加入的 tag 没有写入转换数据库导致的 guid 重复错误,此时需要将 tag 写入转换数据库
             if str(e).find(
                     'SQLITE_CONSTRAINT: UNIQUE constraint failed') > -1:
                 jt = self.jda.get_tag(tag_id)
                 self.cu.add_tag(jt)
             continue
示例#2
0
 def sync_folders(self) -> None:
     """ 同步为知笔记的目录 到 Joplin Folder
     在为知笔记中,目录不是一种资源,它直接在配置文件中定义,在数据库中仅作为 location 字段存在
     而在 Joplin 中,目录是一种标准资源 https://joplinapp.org/api/references/rest_api/#item-type-ids
     """
     waiting_created_l2f = self.cu.get_waiting_for_created_l2f()
     logger.info(f'有 {len(waiting_created_l2f)} 个 folder 等待同步。')
     for l2f in waiting_created_l2f:
         jf = None
         logger.info(f'处理 location {l2f.location}')
         # level1 没有父对象
         if l2f.parent_location is None:
             jf = self.jda.post_folder(title=l2f.title)
             self.cu.update_l2f(l2f.location, jf.id)
         else:
             parent_l2f: Location2Folder = self.cu.l2f_cache.get(
                 l2f.parent_location)
             if parent_l2f is None:
                 msg = f'找不到父对象 {l2f.parent_location}!'
                 logger.error(msg)
                 raise ValueError(msg)
             if parent_l2f.id is None:
                 msg = f'父对象 {l2f.parent_location} 没有 id!'
                 logger.error(msg)
                 raise ValueError(msg)
             jf = self.jda.post_folder(title=l2f.title,
                                       parent_id=parent_l2f.id)
             self.cu.update_l2f(l2f.location, jf.id, jf.parent_id)
     # 更新了 l2f_cache 之后,要更新一次 folders
     self.cu.load_folders()
示例#3
0
    def post_note(self, id: str, title: str, body: str, 
        is_markdown: bool, parent_id: str, source_url: str) -> JoplinNote:
        """ 创建一个新的 Note
        隐藏的 Joplin 参数:通过抓包 Joplin WebClipper
        
        complete Page Html
        source_command
        {
            'name': 'completePageHtml',
            'preProcessFor': 'html'
        }
        convert_to = html

        simplified Page Html
        source_command
        {
            'name': 'simplifiedPageHtml',
        }
        convert_to = markdown

        complete page
        source_command = markdown
        {
            'name': 'completePageHtml',
            'preProcessFor': 'markdown'
        }
        convert_to = markdown
        """
        kwargs = {
            'id': id,
            'title': title,
            'parent_id': parent_id,
            'markup_language': 1,
        }
        if source_url:
            kwargs['source_url'] = source_url
        if is_markdown:
            kwargs['body'] = body
        else:
            # 使用 joplin 的功能将所有的 html 都转换成 markdown
            kwargs['body_html'] = body
            kwargs['convert_to'] = 'markdown'
            kwargs['source_command'] = {
                'name': 'simplifiedPageHtml',
            }

        query = self._build_query()
        logger.info(f'向 Joplin 增加 note {kwargs}')
        resp = self.client.post('/notes', params=query, json=kwargs)
        data = resp.json()
        if data.get('error'):
            logger.error(data['error'])
            raise ValueError(data['error'])
        return JoplinNote(**data)
示例#4
0
 def get_resource(self, guid: str) -> JoplinResource:
     """ 根据 guid 获取 resource
     """
     query = self._build_query(fields=JoplinResource.fields_str())
     resp = self.client.get(f'/resources/{guid}', params=query)
     data = resp.json()
     logger.info(f'从 Joplin 获取 resource {guid}: {data}')
     if data.get('error'):
         logger.error(data['error'])
         raise ValueError(data['error'])
     return JoplinResource(**data)
示例#5
0
 def get_tag(self, guid: str) -> JoplinTag:
     """ 根据 guid 获取 tag
     """
     query = self._build_query(fields=JoplinTag.fields_str())
     resp = self.client.get(f'/tags/{guid}', params=query)
     data = resp.json()
     logger.info(f'从 Joplin 获取 tag {guid}: {data}')
     if data.get('error'):
         logger.error(data['error'])
         raise ValueError(data['error'])
     return JoplinTag(**data)
示例#6
0
 def post_tag(self, **kwargs) -> JoplinTag:
     """ 创建一个新的 tag
     """
     query = self._build_query()
     logger.info(f'向 Joplin 增加 tag {kwargs}')
     resp = self.client.post('/tags', params=query, json=kwargs)
     data = resp.json()
     if data.get('error'):
         logger.error(data['error'])
         raise ValueError(data['error'])
     return JoplinTag(**data)
示例#7
0
 def post_folder(self, **kwargs) -> JoplinFolder:
     """ 创建一个新的 folder
     """
     query = self._build_query()
     logger.info(f'向 Joplin 增加 folder {kwargs}')
     resp = self.client.post('/folders', params=query, json=kwargs)
     data = resp.json()
     if data.get('error'):
         logger.error(data['error'])
         raise ValueError(data['error'])
     return JoplinFolder(**data)
示例#8
0
 def post_resource(self, file: Path, resource_type: int, **kwargs) -> JoplinResource:
     """ 创建一个新的 resources
     """
     query = self._build_query()
     files = {'data': open(file, 'rb')}
     # 经过测试 props 中只有 title 和 id 有作用,其他的参数都无效
     data = {'props': json.dumps(kwargs)}
     logger.info(f'向 Joplin 增加 resource {file} {kwargs}')
     resp = self.client.post('/resources', params=query, files=files, data=data)
     data = resp.json()
     if data.get('error'):
         logger.error(data['error'])
         raise ValueError(data['error'])
     return JoplinResource(**data, resource_type=resource_type)