Skip to content

Instantly share code, notes, and snippets.

@hryk
Created September 5, 2013 12:48
Show Gist options
  • Save hryk/6449662 to your computer and use it in GitHub Desktop.
Save hryk/6449662 to your computer and use it in GitHub Desktop.
It print all PDFs in folder of Mendeley.
#!/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