fafuse 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bdff6603b98ce677b88442e3c2b93d7bd528bdad
4
+ data.tar.gz: d15978fc80986183e7e6d9098d930e17350fd3c8
5
+ SHA512:
6
+ metadata.gz: fc0d10fea9efff98d3683bbddb3a0d73fad356b641bfef85651ec6fc3f09d2c1160317ca4ada5b4201b148c740533f4a14cffba56b3bf2b22f75f37e7536cb86
7
+ data.tar.gz: 16316a53a8c0dc9c017dc85b6d6c628106ea9cbdb10a1913ef0223897ea5edba1cbb91d77742b381aa3a451ead332f9aa8380112976c9f88b9adb562a418bf71
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ *~
2
+ .byebug_history
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fafuse (0.0.1)
5
+ nokogiri (~> 1.7, >= 1.7.2)
6
+ rest-client (~> 2.0, >= 2.0.2)
7
+ rfuse (~> 1.1, >= 1.1.2)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ byebug (9.0.6)
13
+ domain_name (0.5.20170404)
14
+ unf (>= 0.0.5, < 1.0.0)
15
+ http-cookie (1.0.3)
16
+ domain_name (~> 0.5)
17
+ mime-types (3.1)
18
+ mime-types-data (~> 3.2015)
19
+ mime-types-data (3.2016.0521)
20
+ mini_portile2 (2.2.0)
21
+ netrc (0.11.0)
22
+ nokogiri (1.8.0)
23
+ mini_portile2 (~> 2.2.0)
24
+ rest-client (2.0.2)
25
+ http-cookie (>= 1.0.2, < 2.0)
26
+ mime-types (>= 1.16, < 4.0)
27
+ netrc (~> 0.8)
28
+ rfuse (1.1.2)
29
+ unf (0.1.4)
30
+ unf_ext
31
+ unf_ext (0.0.7.4)
32
+
33
+ PLATFORMS
34
+ ruby
35
+
36
+ DEPENDENCIES
37
+ byebug
38
+ fafuse!
39
+
40
+ BUNDLED WITH
41
+ 1.13.6
data/bin/fafuse ADDED
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require "rfuse"
4
+ require "rest-client"
5
+ require "nokogiri"
6
+ require "pathname"
7
+ require "byebug"
8
+
9
+ require "fafuse/all"
10
+
11
+ class FAFuse::Fuse
12
+ DIR_RESOURCES = [
13
+ FAFuse::Root,
14
+ FAFuse::User,
15
+ FAFuse::Gallery,
16
+ FAFuse::Picture
17
+ ]
18
+
19
+ FILE_RESOURCES = [
20
+ FAFuse::UserMetadata,
21
+ FAFuse::PictureMetadata,
22
+ FAFuse::PictureFile
23
+ ]
24
+
25
+ def initialize
26
+ end
27
+
28
+ # The new readdir way, c+p-ed from getdir
29
+ def readdir(ctx, path, filler, offset, ffi)
30
+ DIR_RESOURCES.each do |resource|
31
+ if resource.match?(path)
32
+ object = resource.new(path)
33
+ if object.valid?
34
+ object.content.each do |subdirectory|
35
+ filler.push(subdirectory, getattr(nil, Pathname.new(path).join(subdirectory).to_s), 0)
36
+ end
37
+ return
38
+ else
39
+ raise Errno::ENOENT.new(path)
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ def getattr(ctx, path)
46
+ (DIR_RESOURCES + FILE_RESOURCES).each do |resource|
47
+ if resource.match?(path)
48
+ object = resource.new(path)
49
+ if object.valid?
50
+ return object.stat
51
+ else
52
+ raise Errno::ENOENT.new(path)
53
+ end
54
+ end
55
+ end
56
+ raise Errno::ENOENT.new(path)
57
+ end
58
+
59
+ def open(ctx, path, ffi)
60
+ end
61
+
62
+ def read(ctx, path, size, offset, fi)
63
+ if DIR_RESOURCES.any? { |resource| resource.match?(path) }
64
+ raise Errno::EISDIR.new(path)
65
+ else
66
+ FILE_RESOURCES.each do |resource|
67
+ if resource.match?(path)
68
+ object = resource.new(path)
69
+ if object.valid?
70
+ return object.content[offset..offset + size - 1]
71
+ else
72
+ raise Errno::ENOENT.new(path)
73
+ end
74
+ end
75
+ end
76
+ raise Errno::ENOENT.new(path)
77
+ end
78
+ end
79
+
80
+ # Some random numbers to show with df command
81
+ def statfs(ctx, path)
82
+ s = RFuse::StatVfs.new()
83
+ s.f_bsize = 1024
84
+ s.f_frsize = 1024
85
+ s.f_blocks = 1000000
86
+ s.f_bfree = 500000
87
+ s.f_bavail = 990000
88
+ s.f_files = 10000
89
+ s.f_ffree = 9900
90
+ s.f_favail = 9900
91
+ s.f_fsid = 23423
92
+ s.f_flag = 0
93
+ s.f_namemax = 10000
94
+ return s
95
+ end
96
+
97
+ def poll(ctx, path, ffi, ph, reventsp)
98
+ ph.notifyPoll();
99
+ end
100
+
101
+ def init(ctx, rfuseconninfo)
102
+ end
103
+
104
+ end
105
+
106
+ RFuse.main(ARGV) { fs = FAFuse::Fuse.new() }
data/fafuse.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ lib = File.expand_path("../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require "fafuse/version"
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "fafuse"
9
+ gem.version = FAFuse::VERSION
10
+ gem.authors = ["Victor Goya"]
11
+ gem.email = ["phorque@phorque.it"]
12
+ gem.description = "Fuse wrapper for an art website"
13
+ gem.summary = "Fuse wrapper for an art website"
14
+ gem.homepage = "https://phorque.it"
15
+
16
+ gem.files = `git ls-files -z`.split("\x0")
17
+ gem.executables = %w(fafuse)
18
+ gem.require_paths = ["lib"]
19
+ gem.bindir = 'bin'
20
+
21
+ gem.licenses = ["MIT"]
22
+
23
+ gem.required_ruby_version = "~> 2.0"
24
+
25
+ gem.add_dependency 'rfuse', '~> 1.1', '>= 1.1.2'
26
+ gem.add_dependency 'nokogiri', '~> 1.7', '>= 1.7.2'
27
+ gem.add_dependency 'rest-client', '~> 2.0', '>= 2.0.2'
28
+
29
+ gem.add_development_dependency "byebug"
30
+ end
data/lib/fafuse.rb ADDED
File without changes
data/lib/fafuse/all.rb ADDED
@@ -0,0 +1,7 @@
1
+ require "fafuse/root"
2
+ require "fafuse/user"
3
+ require "fafuse/user_metadata"
4
+ require "fafuse/gallery"
5
+ require "fafuse/picture"
6
+ require "fafuse/picture_metadata"
7
+ require "fafuse/picture_file"
@@ -0,0 +1,59 @@
1
+ require "fafuse/helpers"
2
+
3
+ module FAFuse
4
+ class Gallery
5
+
6
+ attr_accessor :path, :slug
7
+
8
+ def self.match?(path)
9
+ path.match(/^\/([^\.][^\/]+)\/gallery$/)
10
+ end
11
+
12
+ def initialize(path)
13
+ @path = path
14
+ @slug = Gallery.match?(path)[1]
15
+ @resource = RestClient::Resource.new("http://www.furaffinity.net/gallery/")
16
+ end
17
+
18
+ def valid?
19
+ !!slug && slug[0] != "."
20
+ end
21
+
22
+ def stat
23
+ return RFuse::Stat.directory(0555, {
24
+ :uid => 0,
25
+ :gid => 0,
26
+ :atime => Time.now,
27
+ :mtime => Time.now,
28
+ :size => 0
29
+ })
30
+ end
31
+
32
+ def exists?
33
+ Helpers::fa_is_valid?(document)
34
+ end
35
+
36
+ def content
37
+ [].tap do |content|
38
+ loop.with_index do |_, page|
39
+ @gallery = Nokogiri::HTML(@resource[slug][page + 1].get.body)
40
+ break if @gallery.text.include?("There are no submissions to list")
41
+
42
+ pictures = @gallery.css("#gallery-gallery figcaption a").map do |link|
43
+ if link['href'].match(/^\/view\/.+\/$/)
44
+ link['href'].match(/^\/view\/(.+)\/$/)[1]
45
+ end
46
+ end.compact
47
+
48
+ content.concat pictures
49
+ end
50
+ end
51
+ end
52
+
53
+ protected
54
+
55
+ def document
56
+ @document ||= Nokogiri::HTML(@resource[slug].get.body)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,19 @@
1
+ module FAFuse
2
+ class Helpers
3
+ def self.fa_is_unauthorized?(document)
4
+ document.text.include?("content available to registered users only")
5
+ end
6
+
7
+ def self.fa_is_error?(document)
8
+ document.css("title").text =~ /system error/i
9
+ end
10
+
11
+ def self.fa_is_invalid?(document)
12
+ fa_is_unauthorized?(document) || fa_is_error?(document)
13
+ end
14
+
15
+ def self.fa_is_valid?(document)
16
+ !fa_is_invalid?(document)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,56 @@
1
+ require "fafuse/helpers"
2
+
3
+ module FAFuse
4
+ class Picture
5
+
6
+ attr_accessor :path, :id
7
+
8
+ def self.match?(path)
9
+ path.match(/^\/[^\.][^\/]+\/gallery\/([^\.][^\/]+)$/)
10
+ end
11
+
12
+ def initialize(path)
13
+ @id = Picture.match?(path)[1]
14
+ @path = path
15
+ @resource = RestClient::Resource.new("http://www.furaffinity.net/full/")
16
+ end
17
+
18
+ def valid?
19
+ !!id
20
+ end
21
+
22
+ def stat
23
+ RFuse::Stat.directory(0555, {
24
+ :uid => 0,
25
+ :gid => 0,
26
+ :atime => Time.now,
27
+ :mtime => Time.now,
28
+ :size => 0
29
+ })
30
+ end
31
+
32
+ def exists?
33
+ Helpers::fa_is_valid?(document)
34
+ rescue RestClient::NotFound
35
+ false
36
+ end
37
+
38
+ def content
39
+ if exists?
40
+ [ "metadata.json", "file#{format}" ]
41
+ else
42
+ raise Errno::ENOENT.new(path)
43
+ end
44
+ end
45
+
46
+ protected
47
+
48
+ def format
49
+ Pathname.new(document.css("#submissionImg").first["src"]).extname
50
+ end
51
+
52
+ def document
53
+ @document ||= Nokogiri::HTML(@resource[id].get.body)
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,48 @@
1
+ require "fafuse/helpers"
2
+
3
+ module FAFuse
4
+ class PictureFile
5
+
6
+ attr_accessor :path, :id
7
+
8
+ def self.match?(path)
9
+ path.match(/^\/[^\.][^\/]+\/gallery\/([^\.][^\/]+)\/file\.[^\/]+$/)
10
+ end
11
+
12
+ def initialize(path)
13
+ @id = PictureFile.match?(path)[1]
14
+ @path = path
15
+ @resource = RestClient::Resource.new("http://www.furaffinity.net/full/")
16
+ end
17
+
18
+ def valid?
19
+ !!id
20
+ end
21
+
22
+ def stat
23
+ RFuse::Stat.file(0444, {
24
+ :uid => 0,
25
+ :gid => 0,
26
+ :atime => Time.now,
27
+ :mtime => Time.now,
28
+ :size => content.size
29
+ })
30
+ end
31
+
32
+ def exists?
33
+ Helpers::fa_is_valid?(document)
34
+ rescue RestClient::NotFound
35
+ false
36
+ end
37
+
38
+ def content
39
+ RestClient.get(document.css("#submissionImg").first["src"].gsub(/^\/\//, "http://")).body
40
+ end
41
+
42
+ protected
43
+
44
+ def document
45
+ @document ||= Nokogiri::HTML(@resource[id].get.body)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,48 @@
1
+ require "fafuse/helpers"
2
+
3
+ module FAFuse
4
+ class PictureMetadata
5
+
6
+ attr_accessor :path, :id
7
+
8
+ def self.match?(path)
9
+ path.match(/^\/[^\.][^\/]+\/gallery\/([^\.][^\/]+)\/metadata.json$/)
10
+ end
11
+
12
+ def initialize(path)
13
+ @id = PictureMetadata.match?(path)[1]
14
+ @path = path
15
+ @resource = RestClient::Resource.new("http://www.furaffinity.net/full/")
16
+ end
17
+
18
+ def valid?
19
+ !!id
20
+ end
21
+
22
+ def stat
23
+ RFuse::Stat.file(0444, {
24
+ :uid => 0,
25
+ :gid => 0,
26
+ :atime => Time.now,
27
+ :mtime => Time.now,
28
+ :size => content.size
29
+ })
30
+ end
31
+
32
+ def exists?
33
+ Helpers::fa_is_valid?(document)
34
+ rescue RestClient::NotFound
35
+ false
36
+ end
37
+
38
+ def content
39
+ JSON.generate({ id: @id })
40
+ end
41
+
42
+ protected
43
+
44
+ def document
45
+ @document ||= Nokogiri::HTML(@resource[id].get.body)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module FAFuse
2
+ class Root
3
+ attr_accessor :path
4
+
5
+ def self.match?(path)
6
+ path.match(/^\/$/)
7
+ end
8
+
9
+ def initialize(path)
10
+ @path = path
11
+ end
12
+
13
+ def valid?
14
+ true
15
+ end
16
+
17
+ def stat
18
+ RFuse::Stat.directory(0111, {
19
+ :uid => 0,
20
+ :gid => 0,
21
+ :atime => Time.now,
22
+ :mtime => Time.now,
23
+ :size => 0
24
+ })
25
+ end
26
+
27
+ def content
28
+ raise Errno::EACCES.new(path)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,46 @@
1
+ require "fafuse/helpers"
2
+
3
+ module FAFuse
4
+ class User
5
+
6
+ attr_accessor :path, :slug
7
+
8
+ def self.match?(path)
9
+ path.match(/^\/([^\.][^\/]+)$/)
10
+ end
11
+
12
+ def initialize(path)
13
+ @path = path
14
+ @slug = User.match?(path)[1]
15
+ @resource = RestClient::Resource.new("http://www.furaffinity.net/user/")
16
+ end
17
+
18
+ def valid?
19
+ !!slug && slug[0] != "." && exists?
20
+ end
21
+
22
+ def exists?
23
+ Helpers::fa_is_valid?(document)
24
+ end
25
+
26
+ def stat
27
+ return RFuse::Stat.directory(0555, {
28
+ :uid => 0,
29
+ :gid => 0,
30
+ :atime => Time.now,
31
+ :mtime => Time.now,
32
+ :size => 0
33
+ })
34
+ end
35
+
36
+ def content
37
+ [ "metadata.json", "gallery" ]
38
+ end
39
+
40
+ protected
41
+
42
+ def document
43
+ @document ||= Nokogiri::HTML(@resource[slug].get.body)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,47 @@
1
+ require "fafuse/helpers"
2
+ require "json"
3
+
4
+ module FAFuse
5
+ class UserMetadata
6
+
7
+ attr_accessor :path, :slug
8
+
9
+ def self.match?(path)
10
+ path.match(/^\/([^\.][^\/]+)\/metadata.json$/)
11
+ end
12
+
13
+ def initialize(path)
14
+ @path = path
15
+ @slug = UserMetadata.match?(path)[1]
16
+ @resource = RestClient::Resource.new("http://www.furaffinity.net/user/")
17
+ end
18
+
19
+ def valid?
20
+ !!slug && slug[0] != "."
21
+ end
22
+
23
+ def stat
24
+ return RFuse::Stat.file(0444, {
25
+ :uid => 0,
26
+ :gid => 0,
27
+ :atime => Time.now,
28
+ :mtime => Time.now,
29
+ :size => content.size
30
+ })
31
+ end
32
+
33
+ def exists?
34
+ Helpers::fa_is_valid?(document)
35
+ end
36
+
37
+ def content
38
+ JSON.generate({ slug: slug })
39
+ end
40
+
41
+ protected
42
+
43
+ def document
44
+ @document ||= Nokogiri::HTML(@resource[slug].get.body)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,3 @@
1
+ module FAFuse
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fafuse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Victor Goya
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-07-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rfuse
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.2
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.1.2
33
+ - !ruby/object:Gem::Dependency
34
+ name: nokogiri
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.7'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.7.2
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.7'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.7.2
53
+ - !ruby/object:Gem::Dependency
54
+ name: rest-client
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '2.0'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 2.0.2
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '2.0'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 2.0.2
73
+ - !ruby/object:Gem::Dependency
74
+ name: byebug
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ type: :development
81
+ prerelease: false
82
+ version_requirements: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ description: Fuse wrapper for an art website
88
+ email:
89
+ - phorque@phorque.it
90
+ executables:
91
+ - fafuse
92
+ extensions: []
93
+ extra_rdoc_files: []
94
+ files:
95
+ - ".gitignore"
96
+ - Gemfile
97
+ - Gemfile.lock
98
+ - bin/fafuse
99
+ - fafuse.gemspec
100
+ - lib/fafuse.rb
101
+ - lib/fafuse/all.rb
102
+ - lib/fafuse/gallery.rb
103
+ - lib/fafuse/helpers.rb
104
+ - lib/fafuse/picture.rb
105
+ - lib/fafuse/picture_file.rb
106
+ - lib/fafuse/picture_metadata.rb
107
+ - lib/fafuse/root.rb
108
+ - lib/fafuse/user.rb
109
+ - lib/fafuse/user_metadata.rb
110
+ - lib/fafuse/version.rb
111
+ homepage: https://phorque.it
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: '2.0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.5.2
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Fuse wrapper for an art website
135
+ test_files: []