fafuse 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []