File: InotifyPlugin.cs

package info (click to toggle)
muine 0.8.7-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 4,436 kB
  • ctags: 3,081
  • sloc: cs: 12,764; sh: 8,895; ansic: 5,290; xml: 1,408; makefile: 493
file content (156 lines) | stat: -rw-r--r-- 3,767 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

using System;
using System.Collections;
using System.IO;
using Muine.PluginLib;
using Gtk;

namespace Muine
{
	public class InotifyPlugin : Plugin
	{
		private IPlayer player;
		private ThreadNotify notify;

		private ArrayList foldersToAdd = new ArrayList ();
		private ArrayList foldersToRemove = new ArrayList ();
		private ArrayList filesToAdd = new ArrayList ();
		private ArrayList filesToRemove = new ArrayList ();

		public override void Initialize (IPlayer player)
		{
			if (!Inotify.Enabled)
				return;

			this.player = player;

			notify = new ThreadNotify (new ReadyEvent (OnNotify));

			foreach (string dir in player.WatchedFolders)
				Watch (dir);

			player.WatchedFoldersChangedEvent += OnFoldersChanged;
			Inotify.Start ();
		}

		private void OnFoldersChanged ()
		{
			foreach (string dir in player.WatchedFolders)
				Watch (dir);
		}

		private void OnNotify ()
		{
			lock (this)
			{
				foreach (string folder in foldersToAdd)
				{
					//Console.WriteLine ("Adding folder: " + folder);
					Watch (folder);
					player.AddFolder (folder);
				}
				
				foreach (string folder in foldersToRemove)
				{
					//Console.WriteLine ("Removing folder: " + folder);
					player.RemoveFolder (folder);
				}
				
				foreach (string file in filesToAdd) player.AddSong (file);
				
				foreach (string file in filesToRemove) player.RemoveSong (file);
				
				foldersToAdd.Clear ();
				foldersToRemove.Clear ();
				filesToAdd.Clear ();
				filesToRemove.Clear ();
			}
		}

		private bool HasFlag (Inotify.EventType type, Inotify.EventType value)
		{
			return ((type & value) == value);
		}

		private void OnInotifyEvent (Inotify.Watch watch, string path, string subitem,
					     string srcpath, Inotify.EventType type)
		{
			/*
			Console.WriteLine ("Got event ({03}) {0}: {1}/{2}", type, path, subitem,
							   srcpath);
			*/

			string fullPath = Path.Combine (path, subitem);

			lock (this)
			{
				if (HasFlag (type, Inotify.EventType.MovedTo) ||
				    HasFlag (type, Inotify.EventType.CloseWrite))
				{
					if (HasFlag (type, Inotify.EventType.IsDirectory) &&
					    !HasFlag (type, Inotify.EventType.CloseWrite))
					{
						foldersToAdd.Add (fullPath);
						
						if (srcpath != null)
							foldersToRemove.Add (srcpath);
					}
					else
					{
						filesToAdd.Add (fullPath);
						
						if (srcpath != null)
							filesToRemove.Add (srcpath);
					}
					
				}
				else if (HasFlag (type, Inotify.EventType.Create) &&
					 HasFlag (type, Inotify.EventType.IsDirectory))
				{
					Watch (fullPath);
				}
				else if (HasFlag (type, Inotify.EventType.Delete) ||
					 HasFlag (type, Inotify.EventType.MovedFrom))
				{
					if (HasFlag (type, Inotify.EventType.IsDirectory))
						foldersToRemove.Add (fullPath);
					else
						filesToRemove.Add (fullPath);
				}
				
				notify.WakeupMain ();
			}
		}


		private void Watch (string folder)
		{
			/* Do not monitor non existing directories */
			if (!Directory.Exists (folder))
				return;

			/* Do not monitor lost+found directories, since these
			 * are not accesible to mortal users. */
			if (folder.EndsWith("lost+found"))
				return;

			/* Do not monitor trash folders */
			if (folder.EndsWith(".Trash"))
				return;

			/* Do not monitor per-user trash folders, eg. on removable
			 * devices. These are * named ".Trash-username" */
			if (Path.GetFileName(folder).StartsWith(".Trash-"))
				return;

			Inotify.Subscribe (folder, new Inotify.InotifyCallback (OnInotifyEvent),
					   Inotify.EventType.CloseWrite | Inotify.EventType.Delete |
					   Inotify.EventType.Create | Inotify.EventType.MovedFrom |
					   Inotify.EventType.MovedTo);

			foreach (string dir in Directory.GetDirectories (folder)) {
				Watch (dir);
			}
		}
	}
}