Created
September 5, 2013 12:48
-
-
Save hryk/6449662 to your computer and use it in GitHub Desktop.
It print all PDFs in folder of Mendeley.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require "uri" | |
require "rubygems" | |
require "sequel" | |
require "optparse" | |
module Mendeley | |
class FolderNotFound < StandardError; end | |
class GroupNotFound < StandardError; end | |
class MendleyIsMissing < StandardError; end | |
class DatabaseNotFound < StandardError; end | |
class Document | |
attr_reader :id | |
attr_reader :title | |
attr_reader :remote_url | |
def initialize(db, id: nil, title: nil, hash: nil, remoteUrl: nil, localUrl: nil, **kwargs) | |
@db = db | |
@id = id | |
@title = title | |
@attributes = kwargs | |
if hash.nil? || remoteUrl.nil? | |
row = @db[:DocumentFiles].where(documentId: @id).first | |
@hash = row[:hash] | |
@remote_url = row[:remote_url] | |
else | |
@hash = hash | |
@remote_url = remoteUrl | |
end | |
if localUrl.nil? | |
row = @db[:Files].where(hash: @hash).first | |
@local_url = row[:localUrl] | |
else | |
@local_url = localUrl | |
end | |
end | |
def file | |
URI.unescape(URI.parse(@local_url).path) | |
end | |
def method_missing(method_name, *args) | |
attr_name = method_name.to_s.gsub(/(_[a-z])/){|c| c[1].upcase }.to_sym | |
if @attributes.key? attr_name | |
return @attributes[attr_name] | |
else | |
raise NoMethodError | |
end | |
end | |
end | |
class Group | |
attr_reader :id | |
attr_reader :name | |
attr_reader :group_type | |
attr_reader :access | |
attr_reader :public_url | |
attr_reader :is_owner | |
attr_reader :private | |
attr_reader :read_only | |
def initialize(db, id: nil, name: nil, remoteId: nil, access: "PrivateAccess", | |
publicUrl: "", isOwner: false, isReadOnly: false, isPrivate: false, | |
**kwargs) | |
@db = db | |
@name = name | |
@id = id | |
@remote_id = remoteId | |
@access = access | |
@public_url = publicUrl | |
@is_owner = isOwner | |
@read_only = isReadOnly | |
@private = isPrivate | |
end | |
def folders(name=nil) | |
folders = [] | |
filter = {groupId: self.id} | |
if name | |
filter[:name] = name | |
end | |
@db[:Folders].join(:RemoteFolders, folderId: :id).where(filter).each do |row| | |
folders << Folder.new(@db, row) | |
end | |
folders | |
end | |
end | |
class Folder | |
attr_reader :id | |
attr_reader :parent_id | |
attr_reader :remote_id | |
attr_reader :name | |
attr_reader :access | |
def initialize(db, id: nil, name: nil, parentId: -1, | |
access: "PrivateAccess", remoteId: nil, groupId: 0, | |
**kwargs) | |
@db = db | |
@id = id | |
@name = name | |
@parent_id = parentId | |
@access = access | |
@remote_id = remoteId | |
@group_id = groupId | |
end | |
def private? | |
access == "PrivateAccess" | |
end | |
def has_parent? | |
parent_id != -1 | |
end | |
def parent | |
if parent_id != -1 | |
row = @db[:Folders].join(:RemoteFolders, folderId: :id).where(id: parent_id).first | |
Folder.new(@db, row) | |
end | |
nil | |
end | |
def group | |
row = @db[:Groups].where(id: group_id).first | |
Group.new(@db, row) | |
end | |
def documents | |
documents = [] | |
@db[:Documents].join_table(:left_outer, :DocumentFolders, documentId: :id). | |
where(folderId: self.id).each do |row| | |
documents << Document.new(@db, row) | |
end | |
documents | |
end | |
end | |
class App | |
def initialize(mail_addr) | |
@db_path = find_db mail_addr | |
@db = Sequel.connect(URI.escape("sqlite://#{@db_path}")) | |
end | |
def groups(name) | |
groups = [] | |
@db[:Groups].where(name: name).each do |row| | |
groups << Group.new(@db, row) | |
end | |
groups | |
end | |
# if table name is duplicated, restrict with group name. | |
def folders(name, group: nil) | |
if group.nil? | |
if @db[:Folders].where(name: name).count() > 0 | |
folders = [] | |
@db[:Folders].join(:RemoteFolders, folderId: :id).where(name: name).each do |row| | |
folders << Folder.new(@db, row) | |
end | |
folders | |
else | |
raise FolderNotFound | |
end | |
else | |
self.groups(group).first.folders(name) | |
end | |
end | |
protected | |
def find_db(mail_addr) | |
root_dir = File.expand_path(File.join(ENV['HOME'], "Library", "Application Support", "Mendeley Desktop")) | |
if File.directory? root_dir | |
path = File.join(root_dir, "#{mail_addr}@www.mendeley.com.sqlite") | |
if File.file? path | |
return path | |
else | |
raise DatabaseNotFound | |
end | |
else | |
raise MendeleyIsMissing | |
end | |
end | |
end | |
class Group | |
end | |
class Folder | |
end | |
end | |
def main | |
options = {} | |
optparser = OptionParser.new do |opts| | |
opts.banner = "Usage: ./print_all_in_folder [options]" | |
opts.on("-g", "--group [STR]", String, "Specify group by name.") do |v| | |
options[:group] = v | |
end | |
opts.on("-f", "--folder STR", String, "Specify folder by name.") do |v| | |
options[:folder] = v | |
end | |
opts.on("-a", "--account STR", String, "Specify accouint by mail addr.") do |v| | |
options[:mail] = v | |
end | |
opts.on("-h", "--help", "Show this message") do | |
puts opts | |
exit | |
end | |
end | |
optparser.parse! | |
puts options.inspect | |
if options[:folder] && options[:mail] | |
mendeley = Mendeley::App.new(options[:mail]) | |
folder = begin | |
mendeley.folders(options[:folder], group: options[:group]).first | |
rescue Mendeley::FolderNotFound, Mendeley::GroupNotFound | |
puts "folder or group not found." | |
exit(1) | |
end | |
folder.documents.each do |document| | |
escaped_path = document.file.gsub(/[\s\(\)']/, '\ ') | |
system("lp -o sides=two-sided-long-edge #{escaped_path}") | |
end | |
puts "#{folder.documents.size} printed." | |
else | |
puts optparser.help() | |
end | |
end | |
main() | |
__END__ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment