Gogs 1 year ago
parent
commit
5409f97c65
100 changed files with 25674 additions and 25 deletions
  1. 1
    1
      _config.yml
  2. 58
    0
      _posts/2018-09-20-earth-round.md
  3. 11
    0
      _posts/_site/2015-07-07-not-our-department.html
  4. 22
    0
      _posts/_site/2015-09-08-how-i-solve-my-cube.html
  5. 63
    0
      _posts/_site/2016-04-14-one-of-my-favorite-integrals.html
  6. 34
    0
      _posts/_site/2016-07-06-bc-is-a-terrible-calculator.html
  7. 213
    0
      _posts/_site/2018-01-01-chromebook-pixel-arch-linux.html
  8. 202
    0
      _posts/_site/2018-01-19-math-keyboard.html
  9. 38
    0
      _posts/_site/earth-round.html
  10. 0
    23
      _posts/earth-round.md
  11. 7
    1
      assets/css/site.css
  12. 1
    0
      documents/index.html
  13. 177
    0
      librarian/README.md
  14. 40
    0
      librarian/about.php
  15. 288
    0
      librarian/addarticle.php
  16. 1398
    0
      librarian/advancedsearch.php
  17. 55
    0
      librarian/ajaxclipboard.php
  18. 157
    0
      librarian/ajaxdesk.php
  19. 84
    0
      librarian/ajaxdiscussion.php
  20. 13
    0
      librarian/ajaxdisplay.php
  21. 28
    0
      librarian/ajaxemail.php
  22. 184
    0
      librarian/ajaxfilter.php
  23. 11
    0
      librarian/ajaxjournals.php
  24. 537
    0
      librarian/ajaxleftindex.php
  25. 10
    0
      librarian/ajaxlog.php
  26. 18
    0
      librarian/ajaxrating.php
  27. 39
    0
      librarian/ajaxshelf.php
  28. 17
    0
      librarian/ajaxstyles.php
  29. 189
    0
      librarian/ajaxsupplement.php
  30. 60
    0
      librarian/attachment.php
  31. 452
    0
      librarian/authenticate.php
  32. 279
    0
      librarian/backup.php
  33. 810
    0
      librarian/batchimport.php
  34. 74
    0
      librarian/batchreindex.php
  35. 0
    0
      librarian/bin/nothing
  36. 7
    0
      librarian/browsedirs.php
  37. 184
    0
      librarian/categories.php
  38. 83
    0
      librarian/checkbinaries.php
  39. 34
    0
      librarian/citationstyles.php
  40. 28
    0
      librarian/cleartrash.php
  41. 40
    0
      librarian/convertstyles.php
  42. BIN
      librarian/css/custom-theme/images/ui-icons_222222_256x240.png
  43. BIN
      librarian/css/custom-theme/images/ui-icons_404FC3_256x240.png
  44. BIN
      librarian/css/custom-theme/images/ui-icons_FF4500_256x240.png
  45. BIN
      librarian/css/custom-theme/images/ui-icons_ffffff_256x240.png
  46. 7
    0
      librarian/css/custom-theme/jquery-ui-custom.min.css
  47. 1566
    0
      librarian/css/font-awesome.css
  48. 89
    0
      librarian/css/player-controls.css
  49. 296
    0
      librarian/css/plugins.css
  50. 238
    0
      librarian/data.php
  51. 372
    0
      librarian/desktop.php
  52. 335
    0
      librarian/details.php
  53. 131
    0
      librarian/discussion.php
  54. 467
    0
      librarian/display.php
  55. 803
    0
      librarian/download_arxiv.php
  56. 608
    0
      librarian/download_highwire.php
  57. 890
    0
      librarian/download_ieee.php
  58. 962
    0
      librarian/download_nasa.php
  59. 792
    0
      librarian/download_pmc.php
  60. 836
    0
      librarian/download_pubmed.php
  61. 586
    0
      librarian/download_springer.php
  62. 52
    0
      librarian/downloadnewversion.php
  63. 178
    0
      librarian/duplicates.php
  64. 961
    0
      librarian/edit.php
  65. 688
    0
      librarian/expertsearch.php
  66. 1260
    0
      librarian/export.php
  67. 17
    0
      librarian/fatalerror.php
  68. BIN
      librarian/favicon.ico
  69. 151
    0
      librarian/fetch.php
  70. 116
    0
      librarian/fetch_crossref.php
  71. 362
    0
      librarian/fetch_pmc.php
  72. 83
    0
      librarian/file_discussion.php
  73. 546
    0
      librarian/file_top.php
  74. 229
    0
      librarian/files.php
  75. 73
    0
      librarian/flagged.php
  76. 195
    0
      librarian/fonts.php
  77. BIN
      librarian/fonts/FontAwesome.otf
  78. BIN
      librarian/fonts/LiberationSans-Bold.ttf
  79. BIN
      librarian/fonts/LiberationSans-BoldItalic.ttf
  80. BIN
      librarian/fonts/LiberationSans-Italic.ttf
  81. BIN
      librarian/fonts/LiberationSans-Regular.ttf
  82. BIN
      librarian/fonts/fontawesome-webfont.eot
  83. BIN
      librarian/fonts/fontawesome-webfont.otf
  84. 504
    0
      librarian/fonts/fontawesome-webfont.svg
  85. BIN
      librarian/fonts/fontawesome-webfont.ttf
  86. BIN
      librarian/fonts/fontawesome-webfont.woff
  87. 2976
    0
      librarian/functions.php
  88. 54
    0
      librarian/history.php
  89. 68
    0
      librarian/icon.php
  90. 180
    0
      librarian/ilibrarian-default.ini
  91. 30
    0
      librarian/imagelist.php
  92. BIN
      librarian/img/Jcrop.gif
  93. BIN
      librarian/img/ajaxloader.gif
  94. BIN
      librarian/img/ajaxloader2.gif
  95. 148
    0
      librarian/img/bg.svg
  96. BIN
      librarian/img/gridme.png
  97. BIN
      librarian/img/tipsy.gif
  98. 1860
    0
      librarian/importmetadata.php
  99. 19
    0
      librarian/index.html
  100. 0
    0
      librarian/index.inc.php

+ 1
- 1
_config.yml View File

@@ -4,7 +4,7 @@ email: abrahimladha@protonmail.ch
4 4
 description: "Welcome to my site"
5 5
 #logo_location: "https://placehold.it/100x100&text=LOGO"
6 6
 #logo_location: "https://media.giphy.com/media/lWxG18p1SOlEc/giphy.gif"
7
-logo_location: "https://ladha.me/cube1.gif"
7
+logo_location: "https://ladha.me/smash.png"
8 8
 destination: /var/www/html
9 9
 baseurl: "" # the subpath of your site, e.g. /blog/
10 10
 url: "http://ladha.me" # the base hostname & protocol for your site

+ 58
- 0
_posts/2018-09-20-earth-round.md View File

@@ -0,0 +1,58 @@
1
+---
2
+layout: post
3
+date: 2018-09-20 23:08
4
+title: Math over Magic
5
+published: false
6
+---
7
+The world is a lot more boring when you realize somethings can't exist. 
8
+
9
+#Vampires
10
+
11
+Take for example vampires. Vampires are mythical creatures who are immortal and suck
12
+the blood of humans. The people they consume end up turning into more vampires. It
13
+differs a lot from lore to lore and I don't really care to read more about
14
+them. Lets assume (to the contrary) that a vampire exists, and they feast at a
15
+constant rate of once a month, and that all the victims they feast on do turn
16
+into vampires. At the first month, there is one vampire, and they feast on a
17
+human. For the second month, there are now two vampires, and they both feast so
18
+for the third month we have four vampires. We can model the number of vampires
19
+on the planet during month $$n$$ as:
20
+
21
+\begin{equation}
22
+f(n) = 2^{n-1}
23
+\end{equation}
24
+
25
+Lets take a look at three years since we have one vampire, for $$n = 12 \cdot 3
26
+= 36$$, the number of vampires is $$f(n) = 2^{n-1} = 2^35 = 34,359,738,368$$. So in three years
27
+we would have 34 billion vampires. But how can this be when theres only 8
28
+billion people on the planet? All of the population would have to be vampires.
29
+Since I am not a vampire, then vampires cannot exist. 
30
+
31
+#Pinocchio
32
+Pinocchio is a wooden boy who is cursed in such a way that if he tells a lie,
33
+his wooden nose will grow, like a branch. Here we have a physical, measurable
34
+event dependent on the truth/falsehoods of statements, which are imaginary
35
+manmade constructs. For the condition to be met for his nose to grow, pinocchio
36
+has to knowingly tell a lie. If he truly does not no the answer, what he
37
+provides as an answer has no 
38
+
39
+
40
+
41
+#The Earth is round
42
+I got into an argument with some people who believe that the earth is flat.
43
+This made me kind of realize that I am not entirely certain why the earth is
44
+round. Obviously it is, the ships over the horizon, the Erosthanese experiment.
45
+Flat earthers don't even seem certain about their model. They are only certain
46
+enough to deny that the earth is round. I wanted to see if I could come up with
47
+a proof that the earth is round using as few physical assumptions as possible.
48
+Flat earthers will even deny gravity(universal acceleration) as a force
49
+Assumptions:
50
+units for distance
51
+units for time
52
+units for mass
53
+gravity is a force dependent on mass
54
+gravitational force behaves as if the object was a point "center of mass"
55
+
56
+derive inverse square law
57
+concept of potential energy
58
+object of minimal potential energy must be a sphere.

+ 11
- 0
_posts/_site/2015-07-07-not-our-department.html View File

@@ -0,0 +1,11 @@
1
+<p>So you start on your eternal quest for what is truth. You decide to enroll at a University since they seem to know a lot over there. You start at the Art department since its the prettiest building. You sit in a class but no one seems to be interested in giving any answers. People only ask questions for the sake of asking questions, as if thats the only thing to do. When you ask why no one tries to answer anything, they simply say “Not our department”, and then shove you in the direction of Philosophy.</p>
2
+
3
+<p>You enter the Philosophy department. Everyone there seems to be proud and boastful of the questions they ask, as if they are harder, more serious questions than the art departments. But they are still questions. Not the certainty and answers you seek. When you ask them why does no one bother to answer any of the questioned ever asked, they simply say “Not our department”, and point you to the fields of Logic.</p>
4
+
5
+<p>The Logicians seem to be mildly more helpful. You inform them of your quest for truth and seeing your failures in previous departments, they try to be helpful. They ask “Have you tried reason?”. You don't quite understand, so you ask them to elaborate, which they reply: “Not our department” and they set you off to the Natural Sciences.</p>
6
+
7
+<p>These Biologists, Chemists, Physicists, and more, all seem reveled in your appearance. Each believe they are your answer. They pile you up with fact sheets and formulas about What they think is important. Bar charts and standard deviations. Correlations and Causations. Its almost what you are looking for, but not quite. You ask them, “Well this is awfully empirical, Don’t you have anything absolute?” Realizing they have lost a recruit, they say with gloom, “Not our department”. And they set you off to the Mathematicians.</p>
8
+
9
+<p>The Mathematicians never do anything particularly useful, but every useless thing they do with absolute certainty. They study the useless truth that extends beyond a mortal lifespan and past the universes edges. They value answers more than questions, as those answers are the only truth in any world. You do a few proofs, and then you go home and play videogames for 13 hours a day.</p>
10
+
11
+<p>Inspired by Dennetts “<a href="http://www.cs.sfu.ca/~vaughan/teaching/415/papers/dennett-cognitivewheels.html">Cognitive Wheels</a>”.</p>

+ 22
- 0
_posts/_site/2015-09-08-how-i-solve-my-cube.html View File

@@ -0,0 +1,22 @@
1
+<p>I’ve been messing around with my rubix cube and have seen a few different ways to solve it. This is just going to be my list of algorithms in case I forget, so I can so I can come back and remember them.First You have your cube scrambled. Pick a face and solve the cross on top. Then slip in the proper corner pieces. Then do the following algorithm to slot in a piece from the bottom side to the front-left slot.</p>
2
+
3
+<p>D L D’ L’ D’ F’</p>
4
+
5
+<p>Mirror it if you need to do it on the opposite side. Now you should be 2/3rds done. Do this algorithm until you have a cross on top rotating the top face if you do not get it in 3 or 4 tries.</p>
6
+
7
+<p>F U R U’ R’ F’</p>
8
+
9
+<p>Do this to swap the bottom piece on the front face with the top left piece.</p>
10
+
11
+<p>R U R’ U R 2U R’ U</p>
12
+
13
+<p>Swap as many corners as you need to so you get the cross on top to line up with the respective faces. Next see if any of the corners are in the right place (but not nessessarily the correct orientation) and do this algorithm with that corner in the top right. If none are correct, do this algorithm randomly until there is one.</p>
14
+
15
+<p>L R’ U’ R U L’ U’ R’ U R</p>
16
+
17
+<p>Next do this algorithm two or four times until the bottom left corner of the top face matches the square to its left. Once it does, do U’ until there is another bad corner now in the lower left and repeat until the cube is solved. If the cube is not solved eventually this way then your stickers may have been peeled or something.</p>
18
+
19
+<p>R’ D’ R D</p>
20
+
21
+<p>happy cubing :)</p>
22
+

+ 63
- 0
_posts/_site/2016-04-14-one-of-my-favorite-integrals.html View File

@@ -0,0 +1,63 @@
1
+<p>One of the counterexamples that was proposed by Cauchy to LaGranges functional idea was <script type="math/tex">e^{-x^2}</script>. This function, when integrated only has a series solution that cannot be represented by aanother function. You can however, evaluate it as a definite integral from <script type="math/tex">-\infty</script> to <script type="math/tex">\infty</script></p>
2
+
3
+<p>Let</p>
4
+
5
+<p>\begin{equation}
6
+I = \int_{-\infty}^{\infty} e^{-x^2}
7
+\end{equation}</p>
8
+
9
+<p>It might be easier to evaluate its square, so lets do that instead.</p>
10
+
11
+<p>\begin{equation}
12
+I^2 = \int_{-\infty}^{\infty} e^{-x^2}dx \int_{-\infty}^{\infty} e^{-y^2}dy = 
13
+\end{equation}</p>
14
+
15
+<p>\begin{equation}
16
+\int_{-\infty}^{\infty} \int_{-\infty}^{\infty} e^{-x^2}e^{-y^2}dx dy =<br />
17
+\end{equation}</p>
18
+
19
+<p>\begin{equation}
20
+\int_{-\infty}^{\infty} \int_{-\infty}^{\infty} e^{-(x^2 + y^2)}dxdy
21
+\end{equation}</p>
22
+
23
+<p>Well notice that <script type="math/tex">dxdy</script> is really <script type="math/tex">dA</script> and if we switch to polar, <script type="math/tex">-(x^2 + y^2) = -r^2</script></p>
24
+
25
+<p>\begin{equation}
26
+\int_{-\infty}^{\infty} \int_{-\infty}^{\infty} e^{-(x^2 + y^2)}dxdy = 
27
+\end{equation}</p>
28
+
29
+<p>\begin{equation}
30
+\int_{0}^{\infty} \int_{0}^{2\pi} e^{-r^2}rdrd\theta
31
+\end{equation}</p>
32
+
33
+<p>Now we can do a <script type="math/tex">u</script> substition. Let <script type="math/tex">u = -r^2</script> and <script type="math/tex">du = -2r dr</script>.</p>
34
+
35
+<p>\begin{equation}
36
+\int_{0}^{\infty} \int_{0}^{2\pi} e^{-r^2}rdrd\theta
37
+\end{equation}</p>
38
+
39
+<p>\begin{equation}
40
+- \frac{1}{2} \int_{0}^{2\pi} \int_{0}^{-\infty} e^u du d\theta = 
41
+\end{equation}</p>
42
+
43
+<p>\begin{equation}
44
+- 2\pi \frac{1}{2} \int_{0}^{-\infty} e^u du =
45
+\end{equation}</p>
46
+
47
+<p>\begin{equation}
48
+-\pi e^{-r^2} \bigg|_{0}^{\infty}
49
+\end{equation}</p>
50
+
51
+<p>\begin{equation}
52
+-\pi(e^{- \infty} - e^0) = \pi
53
+\end{equation}</p>
54
+
55
+<p>Since <script type="math/tex">I^2 = \pi</script>, then <script type="math/tex">I = \sqrt{\pi}</script>. To summarize:</p>
56
+
57
+<p>\begin{equation}
58
+\int_{-\infty}^{\infty} e^{-x^2}dx = \sqrt{\pi}
59
+\end{equation}</p>
60
+
61
+<p>This is like the coolest thing Ive ever seen for a few reasons. It looks maliciously easy, especially to calc I students. Integrals and derivatives of <script type="math/tex">e</script> are supposed to be easy. This also has a lot of applications in statistics with the gaussian. I haven’t taken a course in probability yet so I don’t really know. Theres also a neat trick where Feynman uses <script type="math/tex">ae^{-x^2}</script> to derive an approximation of Schrodingers equation.</p>
62
+
63
+<p>This post was also really just a testing ground to see if I could get mathjax working. It looks sucessful.</p>

+ 34
- 0
_posts/_site/2016-07-06-bc-is-a-terrible-calculator.html View File

@@ -0,0 +1,34 @@
1
+<p>I’ve been messing around with some terminal based calculators. For my
2
+cryptography class, we had to do some huge computations. Ive noticed that
3
+GNU bc is actually pretty slow at this:</p>
4
+
5
+<div class="highlighter-rouge"><pre class="highlight"><code>[whoishex@localhost ~]$ time echo "(2^2000000)%7" | bc
6
+4
7
+real    0m12.295s
8
+user    0m12.297s
9
+sys     0m0.000s
10
+[whoishex@localhost ~]$
11
+</code></pre>
12
+</div>
13
+
14
+<p>Thats pretty slow! I tried bigger numbers and it would take minutes. In its
15
+place, I’ve started using the python shell.</p>
16
+
17
+<div class="highlighter-rouge"><pre class="highlight"><code>[whoishex@localhost ~]$ time echo "(2**20000000)%7" | python -i 
18
+Python 3.5.2 (default, Jun 28 2016, 08:46:01) 
19
+[GCC 6.1.1 20160602] on linux
20
+Type "help", "copyright", "credits" or "license" for more information.
21
+&gt;&gt;&gt; 4
22
+&gt;&gt;&gt; 
23
+
24
+real    0m0.186s
25
+user    0m0.170s
26
+sys     0m0.017s
27
+[whoishex@localhost ~]$
28
+</code></pre>
29
+</div>
30
+
31
+<p>basically instant. Gnome-calculator, wolfram alpha, and literally any other modern
32
+calculator I can get my hands on is also equally fast. I think bc is trying to
33
+calculate 2^2000000 before modding it out, while the other programs implement
34
+some sort of <a href="https://en.wikipedia.org/wiki/Modular_exponentiation#Memory-efficient_method">method of repeated squares</a>.</p>

+ 213
- 0
_posts/_site/2018-01-01-chromebook-pixel-arch-linux.html View File

@@ -0,0 +1,213 @@
1
+<p>I bought a Chromebook Pixel from 2013 during the Summer of 2016 since I wanted
2
+a new laptop, and these had deprecated in value incredibly considering they
3
+were $1200-1500 when they launched. I picked up the 64GB model for about $400. 
4
+There are a lot of issues with this laptop and maybe I won’t do the
5
+same thing again. The display is incredibly bright and the image can often burn
6
+in if left on for too long. There is basically no cooling on this machine, so
7
+it was constantly at 85 celsius (I found a fix for this later) and the battery
8
+life was pretty terrible. My old C720, I could easily get 12 or 13 hours out of
9
+the thing. I have to charge this every day and be lucky to get 4 hours. Maybe I
10
+was just spoiled. I do like the 4:3 aspect ratio. It makes having two windows
11
+that partition the screen vertically more comfortable on a laptop. The
12
+resolution is also somewhat wasted on me. The fonts I mostly use are usually
13
+all monospaced and pixel perfect, so I don’t see an upgrade for 95% of what I
14
+do on this machine, but PDFs and webpages look like real paper, which is kinda
15
+neat I guess.</p>
16
+
17
+<p><img src="https://ladha.me/IMG/img3.jpg" alt="The machine" title="The machine" height="576px" width="768px" /></p>
18
+
19
+<p>There are two ways you can install linux on this machine. You can leave the
20
+machine in developer mode and keep chromeos, or you can do a small hardware mod
21
+and flash the bios to have a full UEFI ROM. I eventually moved to the UEFI
22
+method since you get some nice things, like suspend-to-disk and no weird error
23
+screen on boot. These instructions are specific to this now 5 year old laptop,
24
+but they could work for any chromebook really.</p>
25
+
26
+<p>We want to flash a UEFI ROM. First we need to remove a single R/W screw from
27
+inside the machine. Power it off and flip it over. The back panel is held down
28
+by 4 screws covered by the little rubber feet. You should have the proper tools
29
+for this. I tried to remove them using a combination of butter knives and
30
+melted pens and I ended stripping one of the miniscule screws. You should buy a
31
+jewelers kit if you are serious enough.</p>
32
+
33
+<p><img src="https://ladha.me/IMG/img2.jpg" alt="The back" title="The back" height="576px" width="768px" /></p>
34
+
35
+<p>They are very very tiny. After taking them out you should feel the backplate be kind of
36
+loose. Use some kind of spudger tool to pry it and be careful of the clips near
37
+the IO ports. I used a guitar pick for the gluey stuff and a plastic butter
38
+knife for the clips. You might need to flex the back a little but be careful.
39
+After the back is off look for a screw that looks like this near the USB ports:</p>
40
+
41
+<p><img src="https://ladha.me/IMG/img1.jpg" alt="The screw" title="The screw" height="1024px" width="768px" /></p>
42
+
43
+<p>I didn’t find any documentation where this screw was on the 2013 model, but
44
+there were pictures of it on the 2015 model, and I removed it to see if it was
45
+the same and sure enough I could write. It also has those telling little
46
+contacts on it. It seems to be smaller than the R/W screw on other chromebooks.
47
+After you remove this screw and the little contact washer on it, clip the back
48
+panel back on and put the screws back in. I didn’t have to glue the feet back on.
49
+There was enough already left on the feet so they just stuck back in.</p>
50
+
51
+<p>After we have removed the screw. Get to a chronos terminal window and run this
52
+command:</p>
53
+
54
+<div class="highlighter-rouge"><pre class="highlight"><code> cd; curl -LO https://mrchromebox.tech/firmware-util.sh &amp;&amp; sudo bash firmware-util.sh
55
+</code></pre>
56
+</div>
57
+
58
+<p>Normally you should be worried about running random scripts off the internet,
59
+but the worst that can happen is that it destroys your operating system. Which
60
+you plan on doing anyway with it. Make sure you save everything you want from
61
+your current chromeos install because doing this next step will nuke
62
+everything. After the script runs you will be dropped in to some basic menu.
63
+You want to select option 3, Installing the full ROM firmware. Follow the steps
64
+and afterwards when you reboot you should be dropped into an intel EFI shell
65
+with some very basic commands. Go make a USB of Arch and plug it in and reboot</p>
66
+
67
+<p>I wanted to make the Instructions for installing Arch as easy as possible
68
+simply by regurgitating commands. So thats what the next list of stuff is with
69
+some included. I came up with this list from several guides modified to better
70
+fit this machine.</p>
71
+
72
+<div class="highlighter-rouge"><pre class="highlight"><code>wifi-menu
73
+</code></pre>
74
+</div>
75
+
76
+<p>Connect to your wifi network, then update, and check if the efi variables are non empty.</p>
77
+
78
+<div class="highlighter-rouge"><pre class="highlight"><code>pacman -Sy
79
+efivar -l
80
+lsblk
81
+gdisk /dev/sda
82
+</code></pre>
83
+</div>
84
+
85
+<p>Once you are in gdisk, type x z y y to clear any all current partitions.</p>
86
+
87
+<div class="highlighter-rouge"><pre class="highlight"><code>cgdisk /dev/sda
88
+</code></pre>
89
+</div>
90
+
91
+<p>We are going to make 3 paritions. A 512MiB root partition. an 8GiB swap
92
+partition, and the remaining as our root partition. Adjust these values if you
93
+want. I think a 4GiB swap size is fine. As long as its bigger than your 4GiB
94
+ram if you want suspend properly.</p>
95
+
96
+<p>boot: new, enter, first sector is blank, size is 512MiB, hex code is EF00, name
97
+is boot</p>
98
+
99
+<p>swap: new, enter first is blank second size is 8GiB, hex code is 8200, name is
100
+swap</p>
101
+
102
+<p>root: new, enter, first is blank, size is blank (remaining), hex code is blank,
103
+name is root</p>
104
+
105
+<p>You want to write those changes and then exit cgdisk. Now we format our partitions:</p>
106
+
107
+<div class="highlighter-rouge"><pre class="highlight"><code>mkfs.fat -F32 /dev/sda1
108
+mkswap /dev/sda2
109
+swapon /dev/sda2
110
+mkfs.ext4 /dev/sda3
111
+mount /dev/sda3 /mnt
112
+mkdir /mnt/boot
113
+mount /dev/sda1 /mnt/boot
114
+cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlistbackup
115
+sed -i 's/^#Server/Server/' /etc/pacman.d/mirrorlistbackup
116
+rankmirrors -n 6 /etc/pacman.d/mirrorlistbackup &gt;&gt; /etc/pacman.d/mirrorlist
117
+pacstrap -i /mnt base base-devel #should download a gigabyte
118
+genfstab -U -p /mnt &gt;&gt; /mnt/etc/fstab
119
+arch-chroot /mnt
120
+uncomment en_US UTF-8 from /etc/locale.gen
121
+locale-gen
122
+echo LANG=en_US.UTF-8 &gt; /etc/locale.conf
123
+export LANG=en_US.UTF-8
124
+ln -s /usr/share/zoneinfo/America/New_York &gt; /etc/localtime
125
+hwclock --systohc --utc
126
+</code></pre>
127
+</div>
128
+
129
+<p>My hostname is “pixel”. You can change yours as well.</p>
130
+
131
+<div class="highlighter-rouge"><pre class="highlight"><code>echo pixel &gt; /etc/hostname
132
+</code></pre>
133
+</div>
134
+
135
+<p>We are also going to enable trim on this since it technically has an SSD. This
136
+will run once a week.</p>
137
+
138
+<div class="highlighter-rouge"><pre class="highlight"><code>systemctl enable fstrim.timer
139
+</code></pre>
140
+</div>
141
+
142
+<p>in /etc/pacman.conf enable multilib by uncommenting [multilib] and the next line</p>
143
+
144
+<div class="highlighter-rouge"><pre class="highlight"><code>pacman -Sy
145
+passwd
146
+</code></pre>
147
+</div>
148
+
149
+<p>now to set up our user:</p>
150
+
151
+<div class="highlighter-rouge"><pre class="highlight"><code>useradd -m -g users -G  wheel,storage,power -s /bin/bash whoishex
152
+visudo
153
+</code></pre>
154
+</div>
155
+
156
+<p>uncomment the wheel line
157
+add to the end of the file <code class="highlighter-rouge">Defaults rootpw</code></p>
158
+
159
+<div class="highlighter-rouge"><pre class="highlight"><code>mount -t efivarfs efivarfs /sys/firmware/efi/efivars/ 
160
+</code></pre>
161
+</div>
162
+
163
+<p>This should say its already mounted. The UEFI ROM does not find where ever grub puts its grubx64.efi file, and there
164
+is a bug where changes to where to find the EFI file do not persist in the UEFI
165
+settings. I have had much more luck with systemd-boot in it getting picked up.</p>
166
+
167
+<div class="highlighter-rouge"><pre class="highlight"><code>bootctl install
168
+pacman -S intel-ucode
169
+</code></pre>
170
+</div>
171
+
172
+<p>in the file <code class="highlighter-rouge">/boot/loader/entries/arch.conf</code></p>
173
+
174
+<div class="highlighter-rouge"><pre class="highlight"><code>title Arch Linux
175
+linux vmlinuz-linux
176
+initrd /intel-ucode.img
177
+initrd /initramfs-linux.img
178
+</code></pre>
179
+</div>
180
+
181
+<p>Exit the file and save it.</p>
182
+
183
+<div class="highlighter-rouge"><pre class="highlight"><code>echo "options root=PARTUUID=$(blkid -s PARTUUID -o value /dev/sda3) rw" &gt;&gt; /boot/loader/entries/arch.conf
184
+</code></pre>
185
+</div>
186
+
187
+<p>You can open up the arch.conf again to see what this did.
188
+We need to find the name of our networking device. Mine is called wlp3s0. You
189
+might have another device if you have an LTE card so enable that as well.</p>
190
+
191
+<div class="highlighter-rouge"><pre class="highlight"><code>ip link
192
+systemctl enable dhcpcd@wlp3s0.service
193
+pacman -S networkmanager
194
+systemctl enable NetworkManager.service
195
+exit
196
+umount -R /mnt
197
+shutdown now
198
+</code></pre>
199
+</div>
200
+
201
+<p>Now unplug the drive and power on. From here you can install your desktop enviroment or window manager. Make sure
202
+you install a display manager like lightdm or gdm so you can login easier.</p>
203
+
204
+<p>To get suspend working edit the file in <code class="highlighter-rouge">/boot/loader/entries/arch.conf</code> to say <code class="highlighter-rouge">options resume=/dev/sda2 root...</code>
205
+change <code class="highlighter-rouge">HandleLidSwitch=hibernate</code> in <code class="highlighter-rouge">/etc/systemd/logind.conf</code>`</p>
206
+
207
+<p>If you want to control the lightbar and fans and thermals. There is a utility
208
+called <code class="highlighter-rouge">ectool</code>. I happened to find a binary version of it <a href="https://github.com/abrahimladha/ectool-chromebook-pixel-2013">here</a>. Move it to <code class="highlighter-rouge">/bin/</code>
209
+and type <code class="highlighter-rouge">ectool help</code> to get started with it.</p>
210
+
211
+<p>You might have some issues with suspending twice.
212
+<a href="https://plus.google.com/+LinusTorvalds/posts/UCoQzy8g2xB">This</a> is the fix for
213
+that.</p>

+ 202
- 0
_posts/_site/2018-01-19-math-keyboard.html View File

@@ -0,0 +1,202 @@
1
+<p>I have been needing a use for an extra keyboard I had sitting in the closet.</p>
2
+
3
+<p><img src="https://ladha.me/IMG/key2.jpg" alt="My desk" title="My desk" height="576px" width="768px" /></p>
4
+
5
+<p>I like to latex all my assignments before turning them in, but I’ve started to
6
+notice that it is taking longer and longer to do so. I took a quantum computing
7
+course recently and the notation in that was abusive. Take for example this
8
+simple glyph:</p>
9
+
10
+<p>\begin{equation}
11
+|\psi_1 \rangle
12
+\end{equation}</p>
13
+
14
+<p>It is really a single character, but It is very complicated. I’d like to be
15
+able to only have to push one button. To type it, even
16
+with texstudio’s autocomplete took 12 key presses. This is for a single
17
+glyph! Only one of the symbols nested in that glyph are actually on my
18
+keyboard. I decided that if I made a new keyboard containing those symbols, I
19
+should be able to write math faster for latex. My goal was to be able to type
20
+at a speed fast enough that I could even be able to do some scratch work in math mode
21
+for latex.</p>
22
+
23
+<p>I wanted this to be as customized to myself as possible. I am sure that many
24
+people use different symbols on a daily basis. I do mostly discrete math so it
25
+is rare that I work with integrals, or other symbols common to other people. 
26
+I store all my latex assignments like
27
+<code class="highlighter-rouge">.../School/Semester/Class/Assignment/hw1.tex</code>. Knowing this I could get a
28
+regex to scan through every latex file I had written and sort by most popular.
29
+The regex ended up looking something like this:</p>
30
+
31
+<div class="highlighter-rouge"><pre class="highlight"><code>grep -o -h -E "\\\\\\w+" ./*/*/*.tex | sort | uniq -c | sort -nr
32
+</code></pre>
33
+</div>
34
+
35
+<p>This outputted a list like:</p>
36
+
37
+<div class="highlighter-rouge"><pre class="highlight"><code>1556 \end
38
+1556 \begin
39
+667 \usepackage
40
+614 \noindent
41
+475 \in
42
+435 \item
43
+429 \frac
44
+320 \alpha
45
+252 \textbf
46
+245 \mathbb
47
+224 \ket
48
+222 \bigskip
49
+199 \implies
50
+...     
51
+</code></pre>
52
+</div>
53
+
54
+<p>First thing to note is I used \begin exactly as many times as I used \end, so thats nice to know!
55
+It had about a 300 entries so I am not going to show them all 
56
+(but they are <a href="https://git.ladha.me/abrahimladha/math-keyboard/src/master/grepped.txt">here</a>). Many were used
57
+only once. I really only needed to look at the most used ones. I also wanted my
58
+keyboard to be fully consistent. I use \ket way way more than I use \bra or
59
+\braket, but If I put \ket, I also wanted to be able to put \bra, and \braket.
60
+I came up with my list of symbols and the next challenge was to design a layout
61
+that would go on top of a keycap set. I first studied how dvorak was created.
62
+Dvorak tried to re-invent the qwerty layout to minimize errors and maximize
63
+speed. He studied hand movements and frequency of letters used in the English
64
+keyboard. The two main things I took away from his work was that, more common
65
+letter should be easier to reach, as well as that characters that have a
66
+similiar probability of being adjacent should be put on opposite hands. To
67
+explain better, if your characters don’t alternate as often as they could, it
68
+is effectly like you are typing with one hand as the second hand is really
69
+waiting for the queue of letters on the first to finish. You cannot type
70
+letters before the ones that come before them have been typed.</p>
71
+
72
+<p>I tried to do the opposite of that in hoping it would have the same effect. Symbols
73
+that had no chance of being adjacent in a word, have a high chance of being
74
+adjacent on my layout. This worked well with the fact many symbols should just
75
+naturally be close to each other. If the \ket is not close to the \bra, it
76
+feels just kind of mentally wrong. When you want a \bra or a \ket, you should
77
+mentally think to the same area of the keyboard.</p>
78
+
79
+<p>Another thing I did was try to group terminals and non terminals from how a
80
+context free grammar might form. I consider symbols that can stand on their own
81
+to be terminals, and everything else to be non terminals. For example
82
+operators, like +,- are non terminals, as well as \ket, \frac, \sum, \choose,
83
+all of these are dependent on following or previous terminals to form a glyph.
84
+Here is my layout:</p>
85
+
86
+<p><img src="https://ladha.me/IMG/layout2cropped.png" alt="Current Layout" title="Current layout" height="256px" width="768px" /></p>
87
+
88
+<p>I put my most common greek letters on the number keys, and on their shift
89
+layer, the capital versions of them. Alpha and Beta dont have capitals so I
90
+threw the terminals infinity and dagger (like, for hermitian operators) on
91
+those keys since I used them infrequently enough, but still wanted them on the
92
+keyboard and had no other room for them. I also use both variations of epsilon.
93
+I use varepsilion for empty strings, among other things and epsilon for
94
+analysis proofs.</p>
95
+
96
+<p>I put the arrow keys right in the middle of the keyboard on hjkl, exactly how
97
+vim has it. I did this because I find that moving my hand to the arrow keys and
98
+then back to the rest position actually wastes quite a bit of time. I have to
99
+readjust and everything. The normal arrow keys still function perfectly fine if
100
+i want to lean back and scroll or something.</p>
101
+
102
+<p>The only terminal I didn’t put on the number keys was the \emptyset, since there 
103
+was no more room. I put it next to the other set nonterminals with \in.</p>
104
+
105
+<p>I also wanted to use this opportunity to enforce better notation on my part.
106
+Sometimes when using modulo I use equal instead of congruence, which doesn’t
107
+really matter all that much, but if I put \cong on the keyboard, I might be
108
+encouraged to do the slightly more correct thing.</p>
109
+
110
+<p>To configure the keyboard softwareside, we are going to use two programs. One
111
+is called xte, which is part of xautomation, and the other is called actkbd.
112
+To start we want to see a list of devices that we have.</p>
113
+
114
+<div class="highlighter-rouge"><pre class="highlight"><code>cat /proc/bus/input/devices
115
+</code></pre>
116
+</div>
117
+
118
+<p>This should list all inputs, even the power
119
+button. This is what an entry should look like</p>
120
+
121
+<div class="highlighter-rouge"><pre class="highlight"><code>I: Bus=0003 Vendor=0f39 Product=1048 Version=0110
122
+N: Name="Heng Yu Technology F-104"
123
+P: Phys=usb-0000:00:12.1-1/input0
124
+S:
125
+Sysfs=/devices/pci0000:00/0000:00:12.1/usb6/6-1/6-1:1.0/0003:0F39:1048.0005/input/input7
126
+U: Uniq=
127
+H: Handlers=sysrq kbd event7 leds 
128
+B: PROP=0
129
+B: EV=120013
130
+B: KEY=e080ffdf01cfffff fffffffffffffffe
131
+B: MSC=10
132
+B: LED=1f
133
+</code></pre>
134
+</div>
135
+
136
+<p>The keyboard i want is called the F-104, so this must be the entry for it. Notice that
137
+under handlers it says <code class="highlighter-rouge">event7</code>. This is important, and will probably
138
+change for you. Just remember this number. Now do</p>
139
+
140
+<div class="highlighter-rouge"><pre class="highlight"><code>sudo actkbd -s -d /dev/input/event7
141
+</code></pre>
142
+</div>
143
+
144
+<p>and start typing on the keyboard. It should tell you the keycodes for each key
145
+input. For example left shift should be 42. Now we need to write a config file
146
+for actkbd. It should be placed in <code class="highlighter-rouge">/etc/actkbd.conf</code>
147
+After a lot of trial and error, this is what mine partially looks like.</p>
148
+
149
+<div class="highlighter-rouge"><pre class="highlight"><code>42:key:ungrabbed,grab,noexec:
150
+42:rel:grabbed,ungrab,noexec:
151
+
152
+16:key:ungrabbed,grab:echo 'str \alpha ' | xte
153
+16:rel:grabbed,ungrab:
154
+16+42:key:grabbed:echo 'str \infty ' | xte
155
+</code></pre>
156
+</div>
157
+
158
+<p>the entries go like, keycode, type, property, and then what is called to
159
+system. When we call <code class="highlighter-rouge">echo 'str \alpha' | xte</code>, xte simulates that string of
160
+keypresses. So what we are doing is physically inputting, then through the
161
+keyboard layer, interrupted by actkbd, to make a systemcall to go back to the
162
+keyboard layer to simulate the correct string. The grab comman is there so that
163
+actkbd will stop the actual keyboard input as well so you don’t get “1\alpha”.
164
+The full config can be found
165
+<a href="https://git.ladha.me/abrahimladha/math-keyboard/src/master/actkbd.conf">here</a>.</p>
166
+
167
+<p>Finally to apply the configuration file you do:</p>
168
+
169
+<div class="highlighter-rouge"><pre class="highlight"><code>sudo actkbd -d /dev/input/event7 -D
170
+</code></pre>
171
+</div>
172
+
173
+<p>When testing around, its better to <code class="highlighter-rouge">sudo kill -9 actkbd</code> before reapplying
174
+an updated config. I have found not doing that while testing creates a ton of
175
+unexpected behavior regarding other inputs.</p>
176
+
177
+<p>To make a pretty picture of the layout, I searched on the internet for a while.
178
+Eventually I found some <a href="https://support.wasdkeyboards.com/hc/en-us/articles/115007847008-Download-Template-Files">inkscape
179
+files</a>
180
+from the wasdkeyboards company for
181
+making and sending them custom layouts to create and purchase. I used latex 
182
+and exported each symbol one by one as an svg. Then I imported them and spent a
183
+few hours arranging everything so it looks nice and even. I printed it out
184
+and taped the picture above my monitor so I can just glance if I don’t know
185
+where something is. If I update the layout I only need to print out a new
186
+picture.</p>
187
+
188
+<p><img src="https://ladha.me/IMG/key1.jpg" alt="taped" title="taped" height="576px" width="768px" /></p>
189
+
190
+<p>From some testing, I would say it has decreased the time for me to type
191
+assignments to
192
+between a half and a third on average. To revisit the glyph from before, it
193
+took me twelve presses. Now it only takes me four.  I also decided against either laser
194
+cutting or putting stickers on the keys to have them actually labelled. I want
195
+this to be a evolving and dynamic layout. I have already added two changes that
196
+I didn’t consider before to the comma key, and Im sure I will change more in
197
+the future as I get interested in different subjects.</p>
198
+
199
+<p>Whats next? Foot pedals maybe? Programming them would be as easy as this, but I don’t
200
+think I could find a use for them. I feel like I have now hit peak
201
+automation, atleast as my input to the computer is concerned. If that will stay is
202
+to be seen.</p>

+ 38
- 0
_posts/_site/earth-round.html View File

@@ -0,0 +1,38 @@
1
+<p>The world is a lot more boring when you realize somethings can’t exist. Take
2
+for example vampires. Vampires are mythical creatures who are immortal and suck
3
+the blood of humans. The people they consume end up turning into more vampires. It
4
+differs a lot from lore to lore and I don’t really care to read more about
5
+them. Lets assume (to the contrary) that a vampire exists, and they feast at a
6
+constant rate of once a month, and that all the victims they feast on do turn
7
+into vampires. At the first month, there is one vampire, and they feast on a
8
+human. For the second month, there are now two vampires, and they both feast so
9
+for the third month we have four vampires. We can model the number of vampires
10
+on the planet during month <script type="math/tex">n</script> as:</p>
11
+
12
+<p>\begin{equation}
13
+f(n) = 2^{n-1}
14
+\end{equation}</p>
15
+
16
+<p>Lets take a look at three years since we have one vampire, for <script type="math/tex">n = 12 \cdot 3
17
+= 36</script>, we have <script type="math/tex">f(n) = 2^{n-1} = 2^35 = 34,359,738,368</script>. So in three years
18
+we would have 34 billion vampires. But how can this be when theres only 8
19
+billion people on the planet? All of the population would have to be vampires.
20
+Since I am not a vampire, then vampires cannot exist.</p>
21
+
22
+<p>I got into an argument with some people who believe that the earth is flat.
23
+This made me kind of realize that I am not entirely certain why the earth is
24
+round. Obviously it is, the ships over the horizon, the Erosthanese experiment.
25
+Flat earthers don’t even seem certain about their model. They are only certain
26
+enough to deny that the earth is round. I wanted to see if I could come up with
27
+a proof that the earth is round using as few physical assumptions as possible.
28
+Flat earthers will even deny gravity(universal acceleration) as a force
29
+Assumptions:
30
+units for distance
31
+units for time
32
+units for mass
33
+gravity is a force dependent on mass
34
+gravitational force behaves as if the object was a point “center of mass”</p>
35
+
36
+<p>derive inverse square law
37
+concept of potential energy
38
+object of minimal potential energy must be a sphere.</p>

+ 0
- 23
_posts/earth-round.md View File

@@ -1,23 +0,0 @@
1
----
2
-layout: post
3
-date: 2015-07-07 23:08
4
-title: Proof the earth is round
5
-published: false
6
----
7
-I got into an argument with some people who believe that the earth is flat.
8
-This made me kind of realize that I am not entirely certain why the earth is
9
-round. Obviously it is, the ships over the horizon, the Erosthanese experiment.
10
-Flat earthers don't even seem certain about their model. They are only certain
11
-enough to deny that the earth is round. I wanted to see if I could come up with
12
-a proof that the earth is round using as few physical assumptions as possible.
13
-Flat earthers will even deny gravity(universal acceleration) as a force
14
-Assumptions:
15
-units for distance
16
-units for time
17
-units for mass
18
-gravity is a force dependent on mass
19
-gravitational force behaves as if the object was a point "center of mass"
20
-
21
-derive inverse square law
22
-concept of potential energy
23
-object of minimal potential energy must be a sphere.

+ 7
- 1
assets/css/site.css View File

@@ -26,11 +26,17 @@ body {
26 26
 /*navbar stuff*/
27 27
 .name-holder{
28 28
   padding:10px;
29
-  color: #002E62;
29
+  color: #000000;
30 30
 }
31 31
 
32 32
 
33 33
 /*Primary navigation bar*/
34
+.navbar {
35
+  background-color: #000000;
36
+}
37
+
38
+
39
+
34 40
 
35 41
 .navbar .navbar-brand {
36 42
   padding: 0px;

+ 1
- 0
documents/index.html View File

@@ -2,6 +2,7 @@
2 2
 layout: page
3 3
 title: Preprints and things
4 4
 ---
5
+<a href="https://theoryclub.github.io/2018/security-cryptocurrency">Provable Security and Cryptocurrency, Big O Theory Club</a><br>
5 6
 <a href="https://ladha.me/files/puzzle_cube.pdf">Cyclic Operations on a Puzzle Cube</a><br>
6 7
 <a href="https://arxiv.org/abs/1612.04518">The Ethereum Scratch Off Puzzle</a><br>
7 8
 <a href="https://ladha.me/files/writeup.pdf">A Secure Set Intersection Protocol using Hamming Distance as a Comparator.</a><br>

+ 177
- 0
librarian/README.md View File

@@ -0,0 +1,177 @@
1
+# I, Librarian Instructions
2
+## Contents
3
+  - Automated installation using installers
4
+  - Windows manual installation
5
+  - Linux manual installation
6
+  - Mac OS X manual installation
7
+  - First use
8
+  - Un-installation
9
+
10
+### Automated installation using installers
11
+You can download and execute installers for Windows Vista, 7, 8, and 10 plus a DEB
12
+package and a console installer for Ubuntu, Debian, and its derivatives. An installer
13
+for Mac OS X is not available. These installers will install and/or configure Apache
14
+and PHP for you. If you don't want that, follow the instructions below to install manually.
15
+
16
+### Windows manual installation
17
+**Before you start, disable Microsoft IIS, close Skype or any other software using port 80.**
18
+  * Install *Apache 2.4+* and *PHP 5.5+* using a Windows installer like WAMPServer.
19
+  * Edit Apache configuration file (httpd.conf). Append this at the end using Notepad:
20
+
21
+```apache_conf
22
+Alias /librarian "C:\I, Librarian"
23
+<Directory "C:\I, Librarian">
24
+    AllowOverride None
25
+    # Allow access from this computer
26
+    Require local
27
+    # Allow access from intranet computers
28
+    Require ip 10
29
+    Require ip 172.16 172.17 172.18 172.19 172.20
30
+    Require ip 172.21 172.22 172.23 172.24 172.25
31
+    Require ip 172.26 172.27 172.28 172.29 172.30 172.31
32
+    Require ip 192.168
33
+    # Insert Allow from directives here to allow access from the internet
34
+    # "Require all granted" opens access to everybody
35
+    <IfModule mod_php5.c>
36
+        php_value upload_max_filesize 400M
37
+        php_value post_max_size 800M
38
+    </IfModule>
39
+    <FilesMatch "\.(ini|conf)$">
40
+        Require all denied
41
+    </FilesMatch>
42
+</Directory>
43
+<Directory "C:\I, Librarian\library">
44
+    Require all denied
45
+</Directory>
46
+```
47
+
48
+You may wish to alter who has access (e.g. to allow access from more IP numbers or domain names) - see the Apache [Authentication and Authorization HOWTO](https://httpd.apache.org/docs/2.4/howto/auth.html) for details.
49
+
50
+  * You may change `C:\I, Librarian` to any directory where you want to have *I, Librarian*,
51
+    including an external drive. For a groupware use, you need to allow access to more IP
52
+    numbers or domain names.
53
+  * Restart the server.
54
+  * Unzip I, Librarian files into the directory defined by `Alias` in `httpd.conf`.
55
+
56
+### Linux manual installation
57
+* If you did not use the DEB package, make sure you have installed these packages from repositories:
58
+  - **apache2 (may be named httpd)**: a web server (you may run *I, Librarian* with a different web server).
59
+  - **php5 (may be named php)**: *I, Librarian* requires PHP5.4.
60
+  - **php5-sqlite (may be named php-pdo)**: SQLite database for PHP5.
61
+  - **php5-gd (may be named php-gd)**: GD library for PHP5.
62
+  - **php5-curl (may be named php-curl)**: curl library for PHP5.
63
+  - **poppler-utils**: required for PDF indexing and for the built-in PDF viewer.
64
+  - **ghostscript**: required for the built-in PDF viewer.
65
+  - **tesseract-ocr**: required for OCR.
66
+  - **libreoffice**: required for conversion of office files to PDF.
67
+* If you are installing from the tar.gz, login as `root` or use `sudo`, and extract files
68
+  into 'librarian' directory in your web sever's root directory. Example:
69
+
70
+```bash
71
+  tar zxf I,-Librarian-*.tar.gz -C /var/www/html/librarian
72
+```
73
+* Change the owner of the library sub-folder to Apache. Example:
74
+
75
+```bash
76
+  chown -R apache:apache /var/www/html/librarian/library
77
+  chown root:root /var/www/html/librarian/library/.htaccess
78
+```
79
+* Insert a safe setting like this example into your Apache configuration file:
80
+
81
+```apache_conf
82
+<Directory "/var/www/html/librarian">
83
+    AllowOverride None
84
+    # Allow access from this computer
85
+    Require local
86
+    # Allow access from intranet computers
87
+    Require ip 10
88
+    Require ip 172.16 172.17 172.18 172.19 172.20
89
+    Require ip 172.21 172.22 172.23 172.24 172.25
90
+    Require ip 172.26 172.27 172.28 172.29 172.30 172.31
91
+    Require ip 192.168
92
+    # Insert Allow from directives here to allow access from the internet
93
+    # "Require all granted" opens access to everybody
94
+    <IfModule mod_php5.c>
95
+        php_value upload_max_filesize 400M
96
+        php_value post_max_size 800M
97
+    </IfModule>
98
+    <FilesMatch "\.(ini|conf)$">
99
+        Require all denied
100
+    </FilesMatch>
101
+</Directory>
102
+<Directory "/var/www/html/librarian/library">
103
+    Require all denied
104
+</Directory>
105
+```
106
+You may wish to alter who has access (e.g. to allow access from more IP numbers or domain names) - see the Apache [Authentication and Authorization HOWTO](https://httpd.apache.org/docs/2.4/howto/auth.html) for details.
107
+
108
+* Restart the server.
109
+
110
+### Mac OS X manual installation
111
+
112
+You will need to have an Apache + PHP stack installed. Details may vary depending on which PHP stack you are using.
113
+
114
+Prior to Mac OS 10.10.1 (Yosemite), the default install of Mac OS included Apache and PHP built with the GD library. However, the PHP installed with     Yosemite does not include GD, so you will need to install one that does:     it is simplest to use the one line installation instructions at [http://php-osx.liip.ch/](http://php-osx.liip.ch/.).
115
+
116
+Edit  /etc/apache2/httpd.conf using a text editor (e.g. TextEdit). You must make two changes:
117
+
118
+* Enabling php, by removing the initial hash symbol from the line beginning "#LoadModule php5_module" (pre-yosemite), or adding a similar line with the path to wherever you installed PHP, eg:
119
+    
120
+    LoadModule php5_module    /usr/local/php5-5.3.29-20141019-211753/libphp5.so
121
+
122
+* Adding a new Directory directive, by inserting: 
123
+
124
+```apache_conf
125
+Alias /librarian /Users/yourusername/Sites/librarian
126
+<Directory /Users/Yourusername/Sites/librarian>
127
+    AllowOverride None
128
+    # Allow access from this computer
129
+    Require local
130
+    # Allow access from intranet computers
131
+    Require ip 10
132
+    Require ip 172.16 172.17 172.18 172.19 172.20
133
+    Require ip 172.21 172.22 172.23 172.24 172.25
134
+    Require ip 172.26 172.27 172.28 172.29 172.30 172.31
135
+    Require ip 192.168
136
+    # Insert Allow from directives here to allow access from the internet
137
+    # "Require all granted" opens access to everybody
138
+    <IfModule mod_php5.c>
139
+        php_value upload_max_filesize 400M
140
+        php_value post_max_size 800M
141
+    </IfModule>
142
+    <FilesMatch "\.(ini|conf)$">
143
+        Require all denied
144
+    </FilesMatch>
145
+</Directory>
146
+<Directory /Users/Yourusername/Sites/librarian/library>
147
+    Require all denied
148
+</Directory>
149
+```
150
+*Don't forget to change "yourusername" to your actual user name. You can find out your user name by typing `whoami` in Terminal.*
151
+
152
+You may wish to alter who has access (e.g. to allow access from more IP numbers or domain names) - see the Apache [Authentication and Authorization HOWTO](https://httpd.apache.org/docs/2.4/howto/auth.html) for details.
153
+
154
+* Restart Apache, by typing `sudo apachectl restart` in Terminal
155
+* Install LibreOffice, Tesseract OCR, Ghostscript, and Poppler.
156
+* Download *I, Librarian* for Mac OSX and double-click the file to extract its contents. Rename the extracted directory to 'librarian' and move it to your *Sites* folder. (alternatively, you could `git clone` this repository).
157
+* Make sure that your *Sites* directory is accessible to *Others*. Use the `Get Info` dialog of the *Sites* directory to change permissions for *Everyone* to access and read (alternatively, run `chmod o+r ~/Sites/` at the terminal). You also need to make sure *Everyone* has **Execute** permissions for your home directory.
158
+* Change the owner of the 'library' sub-folder to the Apache user (_www for the default install). You can do this at the Terminal: `chown -R _www ~/Sites/librarian/library/`.)
159
+* Open your web browser and go to [http://127.0.0.1/librarian](http://127.0.0.1/librarian).
160
+
161
+### First use
162
+* Note on security: These installation instructions allow access to your library only from local computer
163
+  or an internal network. If you open access from the Internet you must change `$hosted` value to `true`
164
+  in data.php, line 10. Failure to do so may open your computer to various attacks.
165
+* In order to start *I, Librarian*, open your web browser, and visit:
166
+  [http://127.0.0.1/librarian](http://127.0.0.1/librarian)
167
+* Replace `127.0.0.1` with your static IP, or qualified server domain name, if you have either one.
168
+* Create an account and head to *Tools->Installation Details* to check if everything checks fine.
169
+* You should also check *Tools->Settings* to run *I, Librarian* the way you want.
170
+
171
+**Thank you for installing *I, Librarian*!**
172
+
173
+### Un-installation
174
+* If you used the DEB package, execute the `uninstall.sh` un-installer.
175
+* Otherwise un-install all programs that you installed solely to use *I, Librarian*.
176
+* These may include Apache and PHP. **Note: You might have other programs using these. Only remove if sure.**
177
+* Delete *I, Librarian* ('librarian') directory.

+ 40
- 0
librarian/about.php View File

@@ -0,0 +1,40 @@
1
+<div style="text-align:center">
2
+    <div class="item-sticker ui-widget-content ui-corner-all" style="margin:auto;margin-top:100px;width:340px">
3
+        <div class="ui-dialog-titlebar ui-state-default ui-corner-top" style="border:0;font-size:1.25em">
4
+            I, Librarian
5
+            <?php
6
+            include_once 'data.php';
7
+            print $version;
8
+            ?>
9
+        </div>
10
+        <div class="separator" style="margin:0"></div>
11
+        <div class="alternating_row ui-corner-bottom" style="padding:4px 12px;overflow:auto;">
12
+            <p>
13
+                Copyright &middot; 2000 - <?php echo date('Y') ?> &middot; Scilico, LLC
14
+            </p>
15
+            <p style="text-align:justify">
16
+                I, Librarian is licensed under GPLv3. The program is provided "as is"
17
+                without warranty of any kind. In no event can the author be liable to
18
+                you for damages arising out of the use or inability to use this software.
19
+                <a href="https://www.gnu.org/licenses/gpl.html" target="_blank">ENTIRE LICENSE</a>
20
+            </p>
21
+        </div>
22
+        <div class="separator" style="margin:0"></div>
23
+        <div class="alternating_row ui-corner-bottom" style="padding:4px 7px;overflow:auto;">
24
+            <h2>
25
+                <a href="https://i-librarian.net/compare.php" target="_blank">
26
+                    <i class="fa fa-question-circle" style="font-size:1em"></i>
27
+                    Buy Support
28
+                </a>
29
+            </h2>
30
+        </div>
31
+        <div class="separator" style="margin:0"></div>
32
+        <div class="alternating_row ui-corner-bottom" style="padding:4px 7px;overflow:auto;">
33
+            <p>
34
+                <b><a href="https://i-librarian.net" target="_blank">I, Librarian web site</a></b>
35
+                <br>
36
+                <a href="https://github.com/mkucej/i-librarian/issues" target="_blank">(issues and sugestions)</a>
37
+            </p>
38
+        </div>
39
+    </div>
40
+</div>

+ 288
- 0
librarian/addarticle.php View File

@@ -0,0 +1,288 @@
1
+<?php
2
+include_once 'data.php';
3
+
4
+if (isset($_SESSION['permissions']) && ($_SESSION['permissions'] == 'A' || $_SESSION['permissions'] == 'U')) {
5
+
6
+    include_once 'functions.php';
7
+
8
+    database_connect(IL_USER_DATABASE_PATH, 'users');
9
+    $user_query = $dbHandle->quote($_SESSION['user_id']);
10
+    $result = $dbHandle->query("SELECT setting_name FROM settings WHERE userID=$user_query AND setting_name LIKE 'remove_%'");
11
+    $settings = $result->fetchAll(PDO::FETCH_ASSOC);
12
+    $result = null;
13
+    $dbHandle = null;
14
+
15
+    foreach ($settings as $setting) {
16
+        ${$setting['setting_name']} = 1;
17
+    }
18
+    ?>
19
+    <div class="leftindex" id="addarticle-left" style="float:left;width:240px;height:100%;overflow:scroll">
20
+        <button id="uploadlink">Add Single Item</button>
21
+        <button id="importlink">Add Multiple Items</button>
22
+        <button id="<?php print ($hosted == false) ? 'batchimportlink' : 'importany'  ?>">Add Multiple PDFs</button>
23
+        <?php
24
+        if ($hosted == false) {
25
+            ?>
26
+            <div style="margin-top:0.5em;padding-left: 10px;width:190px">
27
+                <div class="select-import" id="importlocalhost">from localhost</div>
28
+                <div class="select-import" id="importany">from any computer</div>
29
+            </div>
30
+            <?php
31
+        }
32
+
33
+        database_connect(IL_DATABASE_PATH, 'library');
34
+        $user_query = $dbHandle->quote($_SESSION['user_id']);
35
+        $result = $dbHandle->query("SELECT DISTINCT searchname FROM searches WHERE userID=$user_query ORDER BY searchname ASC");
36
+        $searchnames = $result->fetchAll(PDO::FETCH_COLUMN);
37
+        $result = null;
38
+
39
+        if (!isset($_SESSION['remove_pubmed'])) {
40
+            //HOW MANY FLAGGED?
41
+            $result = $dbHandle->query("SELECT count(*) FROM flagged WHERE userID=" . intval($_SESSION['user_id']) . " AND database='pubmed'");
42
+            if ($result)
43
+                $flagged_count = $result->fetchColumn();
44
+            $result = null;
45
+            ?>
46
+            <button id="pubmedlink" title="Search over 23 million records">PubMed</button>
47
+            <div id="pubmed-container" style="margin-top:0.5em;padding-left: 10px;width:190px">
48
+                <div class="ui-state-default empty-flagged pubmed"><i class="fa fa-trash-o"></i></div>
49
+                <span class="pubmed flagged-items">Flagged Items</span><br>
50
+                &nbsp;&nbsp;<span id="pubmed-flagged-count"><?php print isset($flagged_count) ? $flagged_count : '0'  ?></span>/100
51
+                <div style="clear:both"></div>
52
+                <?php
53
+                while (list($key, $searchname) = each($searchnames)) {
54
+
55
+                    if (substr($searchname, 0, 7) == "pubmed#") {
56
+
57
+                        $searchname_query = $dbHandle->quote($searchname);
58
+                        $result = $dbHandle->query("SELECT searchvalue FROM searches WHERE userID=$user_query AND searchfield='last_search' AND searchname=$searchname_query LIMIT 1");
59
+                        $last_search_stamp = $result->fetchColumn();
60
+                        $result = null;
61
+                        $last_search = round((time() - $last_search_stamp) / 86400, 1);
62
+                        if ($last_search < 1) {
63
+                            $last_search = round((time() - $last_search_stamp) / 3600);
64
+                            $last_search .= ' hour' . (($last_search != 1) ? 's' : '') . ' ago';
65
+                        } elseif ($last_search > 365) {
66
+                            $last_search = '>1 year ago';
67
+                        } else {
68
+                            $last_search = round($last_search);
69
+                            $last_search .= ' day' . (($last_search != 1) ? 's' : '') . ' ago';
70
+                        }
71
+                        if ($last_search_stamp < 2)
72
+                            $last_search = 'Never';
73
+                        print '<div class="pubmed">';
74
+                        print '<div class="ui-state-default del-saved-search pubmed"><i class="fa fa-trash-o"></i></div>';
75
+                        print '<span class="saved-search pubmed" id="saved-search-pubmed-' . htmlspecialchars(rawurlencode(substr($searchname, 7))) . '">';
76
+                        print htmlspecialchars(substr($searchname, 7));
77
+                        print '</span><br>&nbsp;&nbsp;<span>' . $last_search;
78
+                        print '</span></div><div style="clear:both"></div>';
79
+                    }
80
+                }
81
+                reset($searchnames);
82
+                print '</div>';
83
+            }
84
+            if (!isset($_SESSION['remove_pmc'])) {
85
+                //HOW MANY FLAGGED?
86
+                $result = $dbHandle->query("SELECT count(*) FROM flagged WHERE userID=" . intval($_SESSION['user_id']) . " AND database='pmc'");
87
+                if ($result)
88
+                    $flagged_count = $result->fetchColumn();
89
+                $result = null;
90
+                ?>
91
+                <button id="pmclink" title="Search over 3 million records">PubMed Central</button>
92
+                <div id="pmc-container" style="margin-top:0.5em;padding-left: 10px;width:190px">
93
+                    <div class="ui-state-default empty-flagged pmc"><i class="fa fa-trash-o"></i></div>
94
+                    <span class="pmc flagged-items">Flagged Items</span><br>
95
+                    &nbsp;&nbsp;<span id="pmc-flagged-count"><?php print isset($flagged_count) ? $flagged_count : '0'  ?></span>/100
96
+                    <div style="clear:both"></div>
97
+                    <?php
98
+                    while (list($key, $searchname) = each($searchnames)) {
99
+
100
+                        if (substr($searchname, 0, 4) == "pmc#") {
101
+
102
+                            $searchname_query = $dbHandle->quote($searchname);
103
+                            $result = $dbHandle->query("SELECT searchvalue FROM searches WHERE userID=$user_query AND searchfield='pmc_last_search' AND searchname=$searchname_query LIMIT 1");
104
+                            $last_search_stamp = $result->fetchColumn();
105
+                            $result = null;
106
+                            $last_search = round((time() - $last_search_stamp) / 86400, 1);
107
+                            if ($last_search < 1) {
108
+                                $last_search = round((time() - $last_search_stamp) / 3600);
109
+                                $last_search .= ' hour' . (($last_search != 1) ? 's' : '') . ' ago';
110
+                            } elseif ($last_search > 365) {
111
+                                $last_search = '>1 year ago';
112
+                            } else {
113
+                                $last_search = round($last_search);
114
+                                $last_search .= ' day' . (($last_search != 1) ? 's' : '') . ' ago';
115
+                            }
116
+                            if ($last_search_stamp < 2)
117
+                                $last_search = 'Never';
118
+                            print '<div class="pmc">';
119
+                            print '<div class="ui-state-default del-saved-search pmc"><i class="fa fa-trash-o"></i></div>';
120
+                            print '<span class="saved-search pmc" id="saved-search-pmc-' . htmlspecialchars(rawurlencode(substr($searchname, 4))) . '">';
121
+                            print htmlspecialchars(substr($searchname, 4));
122
+                            print '</span><br>&nbsp;&nbsp;<span>' . $last_search;
123
+                            print '</span></div><div style="clear:both"></div>';
124
+                        }
125
+                    }
126
+                    reset($searchnames);
127
+                    print '</div>';
128
+                }
129
+                if (!isset($_SESSION['remove_nasaads'])) {
130
+                    //HOW MANY FLAGGED?
131
+                    $result = $dbHandle->query("SELECT count(*) FROM flagged WHERE userID=" . intval($_SESSION['user_id']) . " AND database='nasaads'");
132
+                    if ($result)
133
+                        $flagged_count = $result->fetchColumn();
134
+                    $result = null;
135
+                    ?>
136
+                    <button id="nasalink" title="Search over 10 million records">NASA ADS</button>
137
+                    <div id="nasaads-container" style="margin-top:0.5em;padding-left: 10px;width:190px">
138
+                        <div class="ui-state-default empty-flagged nasaads"><i class="fa fa-trash-o"></i></div>
139
+                        <span class="nasaads flagged-items">Flagged Items</span><br>
140
+                        &nbsp;&nbsp;<span id="nasaads-flagged-count"><?php print isset($flagged_count) ? $flagged_count : '0'  ?></span>/100
141
+                        <div style="clear:both"></div>
142
+                        <?php
143
+                        while (list($key, $searchname) = each($searchnames)) {
144
+
145
+                            if (substr($searchname, 0, 8) == "nasaads#") {
146
+
147
+                                $searchname_query = $dbHandle->quote($searchname);
148
+                                $result = $dbHandle->query("SELECT searchvalue FROM searches WHERE userID=$user_query AND searchfield='nasa_last_search' AND searchname=$searchname_query LIMIT 1");
149
+                                $last_search_stamp = $result->fetchColumn();
150
+                                $result = null;
151
+                                $last_search = round((time() - $last_search_stamp) / 86400, 1);
152
+                                if ($last_search < 1) {
153
+                                    $last_search = round((time() - $last_search_stamp) / 3600);
154
+                                    $last_search .= ' hour' . (($last_search != 1) ? 's' : '') . ' ago';
155
+                                } elseif ($last_search > 365) {
156
+                                    $last_search = '>1 year ago';
157
+                                } else {
158
+                                    $last_search = round($last_search);
159
+                                    $last_search .= ' day' . (($last_search != 1) ? 's' : '') . ' ago';
160
+                                }
161
+                                if ($last_search_stamp < 2)
162
+                                    $last_search = 'Never';
163
+                                print '<div class="nasaads">';
164
+                                print '<div class="ui-state-default del-saved-search nasaads"><i class="fa fa-trash-o"></i></div>';
165
+                                print '<span class="saved-search nasaads" id="saved-search-nasaads-' . htmlspecialchars(rawurlencode(substr($searchname, 8))) . '">';
166
+                                print htmlspecialchars(substr($searchname, 8));
167
+                                print '</span><br>&nbsp;&nbsp;<span>' . $last_search;
168
+                                print '</span></div><div style="clear:both"></div>';
169
+                            }
170
+                        }
171
+                        reset($searchnames);
172
+                        print '</div>';
173
+                    }
174
+                    if (!isset($_SESSION['remove_arxiv'])) {
175
+                        //HOW MANY FLAGGED?
176
+                        $result = $dbHandle->query("SELECT count(*) FROM flagged WHERE userID=" . intval($_SESSION['user_id']) . " AND database='arxiv'");
177
+                        if ($result)
178
+                            $flagged_count = $result->fetchColumn();
179
+                        $result = null;
180
+                        ?>
181
+                        <button id="arxivlink" title="Search over 1 million records">arXiv</button>
182
+                        <div id="arxiv-container" style="margin-top:0.5em;padding-left: 10px;width:190px">
183
+                            <div class="ui-state-default empty-flagged arxiv"><i class="fa fa-trash-o"></i></div>
184
+                            <span class="arxiv flagged-items">Flagged Items</span><br>
185
+                            &nbsp;&nbsp;<span id="arxiv-flagged-count"><?php print isset($flagged_count) ? $flagged_count : '0'  ?></span>/100
186
+                            <div style="clear:both"></div>
187
+                            <?php
188
+                            while (list($key, $searchname) = each($searchnames)) {
189
+
190
+                                if (substr($searchname, 0, 6) == "arxiv#") {
191
+
192
+                                    $searchname_query = $dbHandle->quote($searchname);
193
+                                    $result = $dbHandle->query("SELECT searchvalue FROM searches WHERE userID=$user_query AND searchfield='arxiv_last_search' AND searchname=$searchname_query LIMIT 1");
194
+                                    $last_search_stamp = $result->fetchColumn();
195
+                                    $result = null;
196
+                                    $last_search = round((time() - $last_search_stamp) / 86400, 1);
197
+                                    if ($last_search < 1) {
198
+                                        $last_search = round((time() - $last_search_stamp) / 3600);
199
+                                        $last_search .= ' hour' . (($last_search != 1) ? 's' : '') . ' ago';
200
+                                    } elseif ($last_search > 365) {
201
+                                        $last_search = '>1 year ago';
202
+                                    } else {
203
+                                        $last_search = round($last_search);
204
+                                        $last_search .= ' day' . (($last_search != 1) ? 's' : '') . ' ago';
205
+                                    }
206
+                                    if ($last_search_stamp < 2)
207
+                                        $last_search = 'Never';
208
+                                    print '<div class="arxiv">';
209
+                                    print '<div class="ui-state-default del-saved-search arxiv"><i class="fa fa-trash-o"></i></div>';
210
+                                    print '<span class="saved-search arxiv" id="saved-search-arxiv-' . htmlspecialchars(rawurlencode(substr($searchname, 6))) . '">';
211
+                                    print htmlspecialchars(substr($searchname, 6));
212
+                                    print '</span><br>&nbsp;&nbsp;<span>' . $last_search;
213
+                                    print '</span></div><div style="clear:both"></div>';
214
+                                }
215
+                            }
216
+                            reset($searchnames);
217
+                            print '</div>';
218
+                        }
219
+//                        if (!isset($_SESSION['remove_ieee'])) {
220
+                        if (false) {
221
+                            ?>
222
+                            <button id="ieeelink" title="Search over 3 million records">IEEE Xplore</button>
223
+                            <div id="ieee-container" style="margin-top:0.5em;padding-left: 10px;width:190px">
224
+                                <?php
225
+                                while (list($key, $searchname) = each($searchnames)) {
226
+
227
+                                    if (substr($searchname, 0, 5) == "ieee#") {
228
+
229
+                                        print '<div class="ieee">';
230
+                                        print '<div class="ui-state-default del-saved-search ieee"><i class="fa fa-trash-o"></i></div>';
231
+                                        print '<span class="saved-search ieee" id="saved-search-ieee-' . htmlspecialchars(rawurlencode(substr($searchname, 5))) . '">';
232
+                                        print htmlspecialchars(substr($searchname, 5));
233
+                                        print '</span></div><div style="clear:both"></div>';
234
+                                    }
235
+                                }
236
+                                reset($searchnames);
237
+                                print '</div>';
238
+                            }
239
+                            if (!isset($_SESSION['remove_springer'])) {
240
+                                ?>
241
+                                <button id="springerlink" title="Search over 8 million records">Springer</button>
242
+                                <div id="springer-container" style="margin-top:0.5em;padding-left: 10px;width:190px">
243
+                                    <?php
244
+                                    while (list($key, $searchname) = each($searchnames)) {
245
+
246
+                                        if (substr($searchname, 0, 9) == "springer#") {
247
+
248
+                                            print '<div class="springer">';
249
+                                            print '<div class="ui-state-default del-saved-search springer"><i class="fa fa-trash-o"></i></div>';
250
+                                            print '<span class="saved-search springer" id="saved-search-springer-' . htmlspecialchars(rawurlencode(substr($searchname, 9))) . '">';
251
+                                            print htmlspecialchars(substr($searchname, 9));
252
+                                            print '</span></div><div style="clear:both"></div>';
253
+                                        }
254
+                                    }
255
+                                    reset($searchnames);
256
+                                    print '</div>';
257
+                                }
258
+                                if (!isset($_SESSION['remove_highwire'])) {
259
+                                    ?>
260
+                                    <button id="highwirelink" title="Search over 7 million records">HighWire Press</button>
261
+                                    <div id="highwire-container" style="margin-top:0.5em;padding-left: 10px;width:190px">
262
+                                        <?php
263
+                                        while (list($key, $searchname) = each($searchnames)) {
264
+
265
+                                            if (substr($searchname, 0, 9) == "highwire#") {
266
+
267
+                                                print '<div class="highwire">';
268
+                                                print '<div class="ui-state-default del-saved-search highwire"><i class="fa fa-trash-o"></i></div>';
269
+                                                print '<span class="saved-search highwire" id="saved-search-highwire-' . htmlspecialchars(rawurlencode(substr($searchname, 9))) . '">';
270
+                                                print htmlspecialchars(substr($searchname, 9));
271
+                                                print '</span></div><div style="clear:both"></div>';
272
+                                            }
273
+                                        }
274
+                                        reset($searchnames);
275
+                                        print '</div>';
276
+                                    }
277
+
278
+                                    $searchnames = null;
279
+                                    $dbHandle = null;
280
+                                    ?>
281
+                                    <br>
282
+                                </div>
283
+                                <div style="height:100%;overflow:auto" id="addarticle-right"></div>
284
+                                <?php
285
+                            } else {
286
+                                print 'Super User or User permissions required.';
287
+                            }
288
+                            ?>

+ 1398
- 0
librarian/advancedsearch.php
File diff suppressed because it is too large
View File


+ 55
- 0
librarian/ajaxclipboard.php View File

@@ -0,0 +1,55 @@
1
+<?php
2
+
3
+include_once 'data.php';
4
+include_once 'functions.php';
5
+
6
+if (isset($_GET['file'])) {
7
+
8
+    database_connect(IL_DATABASE_PATH, 'library');
9
+
10
+    attach_clipboard($dbHandle);
11
+    
12
+    $file_query = $dbHandle->quote($_GET['file']);
13
+
14
+    $dbHandle->beginTransaction();
15
+
16
+    // Does item exist in clipboard?
17
+    $result = $dbHandle->query("SELECT COUNT(*) FROM clipboard.files WHERE id=$file_query");
18
+    $exists = $result->fetchColumn();
19
+    $result = null;
20
+
21
+    if ($exists !== '1') {
22
+
23
+        // Does item still exist in library?
24
+        $result = $dbHandle->query("SELECT COUNT(*) FROM library WHERE id=$file_query");
25
+        $exists = $result->fetchColumn();
26
+        $result = null;
27
+
28
+        if ($exists !== '1')
29
+            die('Error! This item does not exist anymore.');
30
+
31
+        // Can't add over 100,000
32
+        $result = $dbHandle->query("SELECT count(*) FROM clipboard.files");
33
+        $count = $result->fetchColumn();
34
+        $result = null;
35
+        if ($count >= 100000) {
36
+            $dbHandle->rollBack();
37
+            echo 'Error! Clipboard can hold up to 100,000 items.';
38
+            die();
39
+        }
40
+
41
+        // Add item to clipboard.
42
+        $dbHandle->exec("INSERT OR IGNORE INTO clipboard.files (id) VALUES($file_query)");
43
+        echo "added";
44
+    } else {
45
+
46
+        // Remove from clipboard.
47
+        $dbHandle->exec("DELETE FROM clipboard.files WHERE id=$file_query");
48
+        echo "removed";
49
+    }
50
+
51
+    $dbHandle->commit();
52
+
53
+    $dbHandle->exec("DETACH DATABASE clipboard");
54
+    $dbHandle = null;
55
+}    

+ 157
- 0
librarian/ajaxdesk.php View File

@@ -0,0 +1,157 @@
1
+<?php
2
+
3
+include_once 'data.php';
4
+include_once 'functions.php';
5
+
6
+if (isset($_GET['file']) && isset($_GET['project']) && isset($_SESSION['auth'])) {
7
+
8
+    database_connect(IL_DATABASE_PATH, 'library');
9
+    
10
+    $id_query = $dbHandle->quote($_GET['project']);
11
+    $file_query = $dbHandle->quote($_GET['file']);
12
+    
13
+    $dbHandle->beginTransaction();
14
+    
15
+    $result = $dbHandle->query("SELECT rowid FROM projectsfiles WHERE projectID=$id_query AND fileID=$file_query LIMIT 1");
16
+    $rowid = $result->fetchColumn();
17
+    $result = null;
18
+
19
+    if (empty($rowid)) {
20
+        
21
+        $result = $dbHandle->query("SELECT count(*) from projectsfiles WHERE projectID=" . $id_query);
22
+        $count = $result->fetchColumn();
23
+        $result = null;
24
+        if ($count >= 100000) {
25
+            $dbHandle->rollBack();
26
+            echo 'Error! Desk project can hold up to 100,000 items.';
27
+            die();
28
+        }
29
+        $result = $dbHandle->query("SELECT COUNT(*) FROM library WHERE id=$file_query");
30
+        $exists = $result->fetchColumn();
31
+        $result = null;
32
+        if ($exists == 1) {
33
+            $update = $dbHandle->exec("INSERT OR IGNORE INTO projectsfiles (projectID,fileID) VALUES ($id_query,$file_query)");
34
+            if ($update)
35
+                echo 'added';
36
+        } else {
37
+            $dbHandle->rollBack();
38
+            echo 'Error! This item does not exist anymore.';
39
+        }
40
+    } else {
41
+
42
+        $update = $dbHandle->exec("DELETE FROM projectsfiles WHERE rowid=$rowid");
43
+        if ($update)
44
+            echo 'removed';
45
+    }
46
+
47
+    $dbHandle->commit();
48
+    $dbHandle = null;
49
+    die();
50
+}
51
+
52
+if (isset($_GET['adduser']) && isset($_GET['userID']) && isset($_GET['projectID'])) {
53
+
54
+    database_connect(IL_USER_DATABASE_PATH, 'users');
55
+    $user_query = $dbHandle->quote($_GET['userID']);
56
+    $result = $dbHandle->query("SELECT count(*) FROM users WHERE userID=$user_query");
57
+    $exists = $result->fetchColumn();
58
+    $dbHandle = null;
59
+    if ($exists == 1) {
60
+        database_connect(IL_DATABASE_PATH, 'library');
61
+        $user_query = $dbHandle->quote($_GET['userID']);
62
+        $project_query = $dbHandle->quote($_GET['projectID']);
63
+        $dbHandle->exec("INSERT INTO projectsusers (projectID,userID) VALUES ($project_query,$user_query)");
64
+        $dbHandle = null;
65
+        echo 'done';
66
+    } else {
67
+        echo 'Error! This user does not exists.';
68
+    }
69
+    die();
70
+}
71
+
72
+if (isset($_GET['removeuser']) && isset($_GET['userID']) && isset($_GET['projectID'])) {
73
+
74
+    database_connect(IL_DATABASE_PATH, 'library');
75
+    $user_query = $dbHandle->quote($_GET['userID']);
76
+    $project_query = $dbHandle->quote($_GET['projectID']);
77
+    $dbHandle->exec("DELETE FROM projectsusers WHERE projectID=$project_query AND userID=$user_query");
78
+    $dbHandle = null;
79
+
80
+    echo 'done';
81
+    die();
82
+}
83
+
84
+if (isset($_GET['create']) && !empty($_GET['project'])) {
85
+
86
+    database_connect(IL_DATABASE_PATH, 'library');
87
+
88
+    $stmt = $dbHandle->prepare("INSERT INTO projects (userID, project, active) VALUES (:userID, :project, :active)");
89
+
90
+    $stmt->bindParam(':userID', $userID);
91
+    $stmt->bindParam(':project', $project);
92
+    $stmt->bindParam(':active', $active);
93
+
94
+    $userID = $_SESSION['user_id'];
95
+    $project = $_GET['project'];
96
+    $active = '1';
97
+
98
+    $insert = $stmt->execute();
99
+    $dbHandle = null;
100
+
101
+    echo 'done';
102
+    die();
103
+}
104
+
105
+if (isset($_GET['rename']) && !empty($_GET['project']) && isset($_GET['id'])) {
106
+
107
+    database_connect(IL_DATABASE_PATH, 'library');
108
+    $id_query = $dbHandle->quote($_GET['id']);
109
+    $query = $dbHandle->quote($_GET['project']);
110
+    $dbHandle->exec("UPDATE projects SET project=$query WHERE projectID=$id_query");
111
+    $dbHandle = null;
112
+
113
+    echo 'done';
114
+    die();
115
+}
116
+
117
+if (isset($_GET['delete']) && isset($_GET['id'])) {
118
+
119
+    database_connect(IL_DATABASE_PATH, 'library');
120
+    $query = $dbHandle->quote($_GET['id']);
121
+    $dbHandle->beginTransaction();
122
+    $dbHandle->exec("DELETE FROM projects WHERE projectID=$query");
123
+    $dbHandle->exec("DELETE FROM projectsfiles WHERE projectID=$query");
124
+    $dbHandle->exec("DELETE FROM projectsusers WHERE projectID=$query");
125
+    $dbHandle->commit();
126
+    $dbHandle = null;
127
+
128
+    if (is_writable(IL_DATABASE_PATH . DIRECTORY_SEPARATOR . 'project' . intval($_GET['id']) . '.sq3'))
129
+        unlink(IL_DATABASE_PATH . DIRECTORY_SEPARATOR . 'project' . intval($_GET['id']) . '.sq3');
130
+
131
+    echo 'done';
132
+    die();
133
+}
134
+
135
+if (isset($_GET['empty']) && isset($_GET['id'])) {
136
+
137
+    database_connect(IL_DATABASE_PATH, 'library');
138
+    $query = $dbHandle->quote($_GET['id']);
139
+    $dbHandle->exec("DELETE FROM projectsfiles WHERE projectID=$query");
140
+    $dbHandle = null;
141
+
142
+    echo 'done';
143
+    die();
144
+}
145
+
146
+if (isset($_GET['active']) && isset($_GET['projectID'])) {
147
+
148
+    database_connect(IL_DATABASE_PATH, 'library');
149
+    $id_query = $dbHandle->quote($_GET['projectID']);
150
+    $active_query = $dbHandle->quote($_GET['active']);
151
+    $dbHandle->exec("UPDATE projects SET active=" . $active_query . " WHERE projectID=" . $id_query);
152
+    $dbHandle = null;
153
+
154
+    echo 'done';
155
+    die();
156
+}
157
+?>

+ 84
- 0
librarian/ajaxdiscussion.php View File

@@ -0,0 +1,84 @@
1
+<?php
2
+include_once 'data.php';
3
+include_once 'functions.php';
4
+
5
+if (!empty($_GET['project'])) {
6
+    $projectID = intval($_GET['project']);
7
+} elseif (!empty($_POST['project'])) {
8
+    $projectID = intval($_POST['project']);
9
+} else {
10
+    die();
11
+}
12
+
13
+// Check if the user is in this project.
14
+
15
+database_connect(IL_DATABASE_PATH, 'library');
16
+
17
+$stmt = $dbHandle->prepare("SELECT projects.project as p"
18
+        . " FROM projects LEFT OUTER JOIN projectsusers ON projectsusers.projectID=projects.projectID"
19
+        . " WHERE projects.projectID=:projectID AND (projectsusers.userID=:userID OR projects.userID=:userID)");
20
+
21
+$stmt->bindParam(':userID', $_SESSION['user_id'], PDO::PARAM_INT);
22
+$stmt->bindParam(':projectID', $projectID, PDO::PARAM_INT);
23
+
24
+$stmt->execute();
25
+
26
+$result = $stmt->fetch(PDO::FETCH_ASSOC);
27
+
28
+if (empty($result['p'])) {
29
+
30
+    displayError('You are not authorized to see this project.');
31
+}
32
+
33
+$dbHandle = null;
34
+
35
+// Modify discussions.
36
+
37
+database_connect(IL_DATABASE_PATH, 'discussions');
38
+
39
+if(isset($_POST['newmessage']) && !empty($_POST['newmessage'])) {
40
+
41
+	$stmt = $dbHandle->prepare("INSERT INTO projectdiscussion (projectID, user, timestamp, message) VALUES (:projectID, :user, :timestamp, :message)");
42
+
43
+	$stmt->bindParam(':projectID', $projectID);
44
+        $stmt->bindParam(':user', $user);
45
+	$stmt->bindParam(':timestamp', $timestamp);
46
+	$stmt->bindParam(':message', $message);
47
+
48
+	$user = $_SESSION['user'];
49
+	$timestamp = time();
50
+	$message = $_POST['newmessage'];
51
+
52
+	$insert = $stmt->execute();
53
+	$dbHandle = null;
54
+        if ($insert) die('OK');
55
+}
56
+
57
+if(isset($_GET['delete'])) {
58
+
59
+	$delete = $dbHandle->exec("DELETE FROM projectdiscussion WHERE projectID=" . $projectID);
60
+	$dbHandle = null;
61
+        die('OK');
62
+}
63
+
64
+if(isset($_GET['read'])) {
65
+
66
+    $result = $dbHandle->query("SELECT * FROM projectdiscussion WHERE projectID=" . $projectID . " ORDER BY id DESC LIMIT 100");
67
+    $dbHandle = null;
68
+
69
+    print '<table>';
70
+
71
+    while($message = $result->fetch(PDO::FETCH_ASSOC)) {
72
+
73
+        $message['user'] = htmlspecialchars($message['user']);
74
+	$message['message'] = htmlspecialchars($message['message']);
75
+	$message['message'] = preg_replace('/(https?\:\/\/\S+)/i', '<a href="\\1" target="_blank">\\1</a>', $message['message']);
76
+	$message['message'] = nl2br($message['message']);
77
+
78
+        echo "<div class=\"alternating_row\" style=\"padding:2px\"><b>" . date("M j, Y, h:i:s A", $message['timestamp']) . ", " . $message['user'] . ":</b></div>";
79
+        echo "<div style=\"padding:2px 2px 10px 2px\">$message[message]</div>" . PHP_EOL;
80
+    }
81
+
82
+    print '</table>';
83
+}
84
+?>

+ 13
- 0
librarian/ajaxdisplay.php View File

@@ -0,0 +1,13 @@
1
+<?php
2
+include_once 'data.php';
3
+
4
+if (in_array($_GET['value'], array('brief','summary','abstract','icons'))) {
5
+    $_SESSION['display'] = $_GET['value'];
6
+} elseif (in_array($_GET['value'], array('id','year','journal','rating','title'))) {
7
+    $_SESSION['orderby'] = $_GET['value'];
8
+} elseif (in_array($_GET['value'], array('5','10','15','20','50','100'))) {
9
+    $_SESSION['limit'] = $_GET['value'];
10
+} else {
11
+    echo 'Error! Invalid value.';
12
+}
13
+?>

+ 28
- 0
librarian/ajaxemail.php View File

@@ -0,0 +1,28 @@
1
+<?php
2
+
3
+// BACK END TO E-MAIL BUTTON
4
+
5
+include_once 'data.php';
6
+include_once 'functions.php';
7
+
8
+if (isset($_GET['id']) && is_numeric($_GET['id'])) {
9
+
10
+    database_connect(IL_DATABASE_PATH, 'library');
11
+    $id_query = $dbHandle->quote($_GET['id']);
12
+    $result = $dbHandle->query("SELECT title,abstract,doi FROM library WHERE id=" . $id_query);
13
+    $row = $result->fetch(PDO::FETCH_ASSOC);
14
+    $result = null;
15
+    $dbHandle = null;
16
+
17
+    if (!is_array($row))
18
+        die('Error!<br>Item does not exist.');
19
+
20
+    extract($row);
21
+
22
+    die('mailto:?subject=Paper in I, Librarian&body=' . wordwrap($title, 65, '%0A', true) . '%0A%0A'
23
+            . wordwrap(substr($abstract, 0, 500), 65, '%0A', true)
24
+            . (strlen($abstract) > 500 ? '...' : '') . '%0A%0A'
25
+            . (!empty($doi) ? 'Publisher link:%0Ahttps://dx.doi.org/' . $doi . '%0A%0A' : '')
26
+            . 'I, Librarian link:%0A' . IL_URL . '?id=' . $_GET['id'] . '%0A%0A');
27
+}
28
+?>

+ 184
- 0
librarian/ajaxfilter.php View File

@@ -0,0 +1,184 @@
1
+<?php
2
+
3
+include_once 'data.php';
4
+include_once 'functions.php';
5
+session_write_close();
6
+
7
+if (!isset($_GET['select']) || ($_GET['select'] != 'library' &&
8
+        $_GET['select'] != 'shelf' &&
9
+        $_GET['select'] != 'project' &&
10
+        $_GET['select'] != 'clipboard')) {
11
+
12
+    $_GET['select'] = 'library';
13
+}
14
+
15
+database_connect(IL_DATABASE_PATH, 'library');
16
+
17
+$in = '';
18
+
19
+if ($_GET['select'] == 'shelf') {
20
+    $in = "id IN (SELECT fileID FROM shelves WHERE fileID>0 AND userID=" . intval($_SESSION['user_id']) . ")";
21
+}
22
+
23
+if ($_GET['select'] == 'clipboard') {
24
+    attach_clipboard($dbHandle);
25
+    $in = "id IN (SELECT id FROM clipboard.files)";
26
+}
27
+
28
+empty($in) ? $and = '' : $and = 'AND';
29
+
30
+if (isset($_GET['term']))
31
+    $_GET['filter'] = $_GET['term'];
32
+
33
+if (isset($_GET['filter'])) {
34
+    $filter = $_GET['filter'];
35
+    $filter_query = $dbHandle->quote("%$filter%");
36
+} else {
37
+    die();
38
+}
39
+
40
+######################################################################
41
+
42
+if (isset($_GET['open']) && in_array("authors", $_GET['open'])) {
43
+
44
+    $filter_arr = array();
45
+    if (strstr($filter, ',') !== 0)
46
+        $filter_arr = explode(',', $filter);
47
+    if (!empty($filter_arr[0]))
48
+        $author_filter = $dbHandle->quote('%L:"' . trim($filter_arr[0]) . '%');
49
+    if (!empty($filter_arr[1]))
50
+        $author_filter = $dbHandle->quote('%L:"' . trim($filter_arr[0]) . '",F:"' . trim($filter_arr[1]) . '%');
51
+
52
+    $result = $dbHandle->query("SELECT authors || ';' || authors_ascii FROM library WHERE $in $and (authors LIKE $author_filter OR authors_ascii LIKE $author_filter)");
53
+    $authors = $result->fetchAll(PDO::FETCH_COLUMN);
54
+
55
+    $dbHandle = null;
56
+
57
+    $authors_string = '';
58
+
59
+    $authors_string = implode(";", $authors);
60
+    $authors = explode(";", $authors_string);
61
+
62
+    function filter_authors($var) {
63
+        global $filter_arr;
64
+        return stripos($var, 'L:"' . trim($filter_arr[0])) === 0;
65
+    }
66
+
67
+    $authors = array_filter($authors, 'filter_authors');
68
+
69
+    if (empty($authors)) {
70
+        if (isset($_GET['term'])) {
71
+            echo json_encode(array());
72
+        } else {
73
+            echo 'No such authors.';
74
+        }
75
+        die();
76
+    }
77
+
78
+    $authors_unique = array_unique($authors);
79
+    usort($authors_unique, "strnatcasecmp");
80
+
81
+    $json_authors = array();
82
+
83
+    while (list($key, $authors) = each($authors_unique)) {
84
+        $authors = str_replace('L:"', '', $authors);
85
+        $authors = str_replace('",F:"', ', ', $authors);
86
+        $authors = substr($authors, 0, -1);
87
+        $json_authors[] = $authors;
88
+        if (!isset($_GET['term'])) print PHP_EOL . '<span class="author" id="' . urlencode($authors) . '">' . htmlspecialchars($authors) . '</span><br>';
89
+    }
90
+
91
+    // autocomplete
92
+    if (isset($_GET['term']))
93
+        echo json_encode($json_authors);
94
+}
95
+
96
+######################################################################
97
+
98
+if (isset($_GET['open']) && in_array("keywords", $_GET['open'])) {
99
+
100
+    $result = $dbHandle->query("SELECT keywords FROM library WHERE $in $and keywords LIKE $filter_query");
101
+    $keywords = $result->fetchAll(PDO::FETCH_COLUMN);
102
+    $dbHandle = null;
103
+
104
+    $keywords_string = '';
105
+    $keywords_string = implode("/", $keywords);
106
+    $keywords = explode("/", $keywords_string);
107
+
108
+    foreach ($keywords as $value) {
109
+        $trimmed_keywords[] = trim($value);
110
+    }
111
+
112
+    $trimmed_keywords = array_filter($trimmed_keywords);
113
+
114
+    if (empty($trimmed_keywords)) {
115
+        print 'No such keywords.';
116
+        die();
117
+    }
118
+
119
+    $keywords_array = array_unique($trimmed_keywords);
120
+    usort($keywords_array, "strnatcasecmp");
121
+
122
+    while (list($key, $keywords) = each($keywords_array)) {
123
+        if (!empty($keywords) && stripos($keywords, $filter) !== false) {
124
+            print '<span class="key" id="' . htmlspecialchars(urlencode($keywords)) . '">' . htmlspecialchars($keywords) . '</span><br>';
125
+        }
126
+    }
127
+}
128
+
129
+######################################################################
130
+
131
+if (isset($_GET['open']) && in_array("editors", $_GET['open'])) {
132
+
133
+    $filter_arr = array();
134
+    if (strstr($filter, ',') !== 0)
135
+        $filter_arr = explode(',', $filter);
136
+    if (!empty($filter_arr[0]))
137
+        $author_filter = $dbHandle->quote('%L:"' . trim($filter_arr[0]) . '%');
138
+    if (!empty($filter_arr[1]))
139
+        $author_filter = $dbHandle->quote('%L:"' . trim($filter_arr[0]) . '",F:"' . trim($filter_arr[1]) . '%');
140
+
141
+    $result = $dbHandle->query("SELECT editor FROM library WHERE $in $and (editor LIKE $author_filter)");
142
+    $authors = $result->fetchAll(PDO::FETCH_COLUMN);
143
+
144
+    $dbHandle = null;
145
+
146
+    $authors_string = '';
147
+
148
+    $authors_string = implode(";", $authors);
149
+    $authors = explode(";", $authors_string);
150
+
151
+    function filter_authors($var) {
152
+        global $filter_arr;
153
+        return stripos($var, 'L:"' . trim($filter_arr[0])) === 0;
154
+    }
155
+
156
+    $authors = array_filter($authors, 'filter_authors');
157
+
158
+    if (empty($authors)) {
159
+        if (isset($_GET['term'])) {
160
+            echo json_encode(array());
161
+        } else {
162
+            echo 'No such editors.';
163
+        }
164
+        die();
165
+    }
166
+
167
+    $authors_unique = array_unique($authors);
168
+    usort($authors_unique, "strnatcasecmp");
169
+
170
+    $json_authors = array();
171
+
172
+    while (list($key, $authors) = each($authors_unique)) {
173
+        $authors = str_replace('L:"', '', $authors);
174
+        $authors = str_replace('",F:"', ', ', $authors);
175
+        $authors = substr($authors, 0, -1);
176
+        $json_authors[] = $authors;
177
+        if (!isset($_GET['term'])) print PHP_EOL . '<span class="author" id="' . urlencode($authors) . '">' . htmlspecialchars($authors) . '</span><br>';
178
+    }
179
+
180
+    // autocomplete
181
+    if (isset($_GET['term']))
182
+        echo json_encode($json_authors);
183
+}
184
+?>

+ 11
- 0
librarian/ajaxjournals.php View File

@@ -0,0 +1,11 @@
1
+<?php
2
+include_once 'data.php';
3
+include_once 'functions.php';
4
+database_connect(IL_DATABASE_PATH, 'library');
5
+$query = $dbHandle->quote ('%'.$_GET['term'].'%');
6
+if ($_GET['search'] == 'journal') $result = $dbHandle->query("SELECT DISTINCT journal FROM library WHERE journal LIKE $query ORDER BY journal ASC");
7
+if ($_GET['search'] == 'secondary_title') $result = $dbHandle->query("SELECT DISTINCT secondary_title FROM library WHERE secondary_title LIKE $query ORDER BY secondary_title ASC");
8
+$dbHandle = null;
9
+$journals = $result->fetchAll(PDO::FETCH_COLUMN);
10
+echo json_encode($journals);
11
+?>

+ 537
- 0
librarian/ajaxleftindex.php View File

@@ -0,0 +1,537 @@
1
+<?php
2
+
3
+include_once 'data.php';
4
+include_once 'functions.php';
5
+session_write_close();
6
+
7
+// CACHING
8
+
9
+$cache_name = cache_name();
10
+$db_change = database_change(array(
11
+    'library',
12
+    'shelves',
13
+    'filescategories',
14
+    'searches',
15
+    'categories'
16
+        ), array(), array('clipboard'));
17
+cache_start($db_change);
18
+
19
+if (!isset($_GET['select']))
20
+    $_GET['select'] = 'library';
21
+
22
+if ($_GET['select'] != 'library' &&
23
+        $_GET['select'] != 'shelf' &&
24
+        $_GET['select'] != 'project' &&
25
+        $_GET['select'] != 'clipboard') {
26
+
27
+    $_GET['select'] = 'library';
28
+}
29
+
30
+database_connect(IL_DATABASE_PATH, 'library');
31
+
32
+$in = '';
33
+
34
+if ($_GET['select'] == 'shelf') {
35
+    $in = "INNER JOIN shelves ON library.id=shelves.fileID WHERE shelves.userID=" . intval($_SESSION['user_id']);
36
+}
37
+
38
+if ($_GET['select'] == 'clipboard') {
39
+    attach_clipboard($dbHandle);
40
+    $in = "WHERE id IN (SELECT id FROM clipboard.files)";
41
+}
42
+
43
+empty($in) ? $where = 'WHERE' : $where = 'AND';
44
+
45
+### CATEGORY ###################################################################
46
+
47
+if (isset($_GET['open']) && in_array("category", $_GET['open'])) {
48
+
49
+    $subfiles = '';
50
+
51
+    if ($_GET['select'] == 'shelf' || $_GET['select'] == 'clipboard') {
52
+        $dbHandle->exec("PRAGMA temp_store = MEMORY");
53
+        $dbHandle->exec("PRAGMA synchronous = OFF");
54
+        $dbHandle->exec("CREATE TEMPORARY TABLE subfiles (fileID INTEGER PRIMARY KEY)");
55
+        $subfiles = "filescategories.fileID IN (SELECT fileID FROM subfiles)";
56
+    }
57
+
58
+    if ($_GET['select'] == 'shelf') {
59
+        $dbHandle->exec("INSERT INTO subfiles SELECT fileID FROM shelves WHERE userID=" . intval($_SESSION['user_id']) . "");
60
+    }
61
+
62
+    if ($_GET['select'] == 'clipboard') {
63
+
64
+        attach_clipboard($dbHandle);
65
+        $dbHandle->exec("INSERT INTO subfiles (fileID) SELECT id FROM clipboard.files");
66
+        }
67
+
68
+    $categories_to_search = array_keys($_GET['open'], 'category');
69
+
70
+    ###first level open###
71
+
72
+    if (empty($categories_to_search[0])) {
73
+
74
+        if (!empty($subfiles))
75
+            $subfiles = "WHERE " . $subfiles;
76
+
77
+        if ($_GET['select'] == 'library') {
78
+            $result = $dbHandle->query("SELECT categoryID,category
79
+			FROM categories 
80
+			ORDER BY category COLLATE NOCASE ASC");
81
+        } elseif ($_GET['select'] == 'shelf' || $_GET['select'] == 'clipboard') {
82
+            $result = $dbHandle->query("SELECT DISTINCT categories.categoryID AS categoryID,category
83
+			FROM filescategories
84
+			INNER JOIN categories ON filescategories.categoryID=categories.categoryID
85
+			$subfiles
86
+			ORDER BY category COLLATE NOCASE ASC");
87
+        }
88
+
89
+        print '<div>';
90
+
91
+        print PHP_EOL . '<div id="cat-0"><span class="cat1">!unassigned</span><div></div></div>';
92
+
93
+        while ($categories = $result->fetch(PDO::FETCH_ASSOC)) {
94
+
95
+            print PHP_EOL . '<div id="cat-' . $categories['categoryID'] . '"><span class="cat1">' . htmlspecialchars($categories['category'])
96
+                    . '</span><div style="margin-left:15px;white-space: nowrap"></div></div>';
97
+        }
98
+
99
+        print '</div>';
100
+    }
101
+
102
+    ###second level open###
103
+
104
+    if (!empty($categories_to_search[0]) && empty($categories_to_search[1]) && empty($categories_to_search[2])) {
105
+
106
+        if (!empty($subfiles))
107
+            $subfiles = $subfiles . " AND";
108
+
109
+        $category_query = $dbHandle->quote($categories_to_search[0]);
110
+
111
+        $result = $dbHandle->query("SELECT categoryID,category
112
+			FROM categories
113
+			WHERE categoryID IN (SELECT categoryID
114
+				FROM filescategories
115
+				WHERE $subfiles fileID IN (SELECT fileID FROM filescategories WHERE categoryID=$category_query)
116
+					AND NOT categoryID IN ($category_query))
117
+			ORDER BY category COLLATE NOCASE ASC");
118
+
119
+        $lines = array();
120
+
121
+        while ($categories = $result->fetch(PDO::FETCH_ASSOC)) {
122
+
123
+            $is_category = '';
124
+
125
+            print PHP_EOL . '<div id="cat-' . $categories['categoryID'] . '"><span class="cat2">- ' . htmlspecialchars($categories['category'])
126
+                    . '</span><div style="margin-left:20px;white-space:nowrap"></div></div>';
127
+        }
128
+
129
+        if (!isset($is_category)) {
130
+            print 'No further categories.';
131
+            die();
132
+        }
133
+    }
134
+
135
+    ###third level open###
136
+
137
+    if (!empty($categories_to_search[0]) && !empty($categories_to_search[1]) && empty($categories_to_search[2])) {
138
+
139
+        if (!empty($subfiles))
140
+            $subfiles = $subfiles . " AND";
141
+
142
+        $category_query1 = $dbHandle->quote($categories_to_search[0]);
143
+        $category_query2 = $dbHandle->quote($categories_to_search[1]);
144
+
145
+        $result = $dbHandle->query("SELECT categoryID,category
146
+			FROM categories
147
+			WHERE categoryID IN (SELECT categoryID
148
+				FROM filescategories
149
+				WHERE $subfiles fileID IN (SELECT fileID FROM filescategories WHERE categoryID=$category_query1 INTERSECT SELECT fileID FROM filescategories WHERE categoryID=$category_query2)
150
+					AND NOT categoryID IN ($category_query1,$category_query2))
151
+			ORDER BY category COLLATE NOCASE ASC");
152
+
153
+        while ($categories = $result->fetch(PDO::FETCH_ASSOC)) {
154
+
155
+            $is_category = '';
156
+
157
+            print PHP_EOL . '<div id="cat-' . $categories['categoryID'] . '"><span class="cat3"><b>&middot;</b> ' . htmlspecialchars($categories['category'])
158
+                    . '</span><div style="margin-left:20px;white-space:nowrap"></div></div>';
159
+        }
160
+
161
+        if (!isset($is_category)) {
162
+            print 'No further categories.';
163
+            die();
164
+        }
165
+    }
166
+
167
+    ###fourth level open###
168
+
169
+    if (!empty($categories_to_search[0]) && !empty($categories_to_search[1]) && !empty($categories_to_search[2])) {
170
+
171
+        if (!empty($subfiles))
172
+            $subfiles = $subfiles . " AND";
173
+
174
+        $category_query1 = $dbHandle->quote($categories_to_search[0]);
175
+        $category_query2 = $dbHandle->quote($categories_to_search[1]);
176
+        $category_query3 = $dbHandle->quote($categories_to_search[2]);
177
+
178
+        $result = $dbHandle->query("SELECT categoryID,category
179
+			FROM categories
180
+			WHERE categoryID IN (SELECT categoryID
181
+				FROM filescategories
182
+				WHERE $subfiles fileID IN (SELECT fileID FROM filescategories WHERE categoryID=$category_query1
183
+								INTERSECT SELECT fileID FROM filescategories WHERE categoryID=$category_query2
184
+								INTERSECT SELECT fileID FROM filescategories WHERE categoryID=$category_query3)
185
+				AND NOT categoryID IN ($category_query1,$category_query2,$category_query3))
186
+			ORDER BY category COLLATE NOCASE ASC");
187
+
188
+        while ($categories = $result->fetch(PDO::FETCH_ASSOC)) {
189
+
190
+            $is_category = '';
191
+
192
+            print PHP_EOL . '<span class="cat4" id="cat-' . $categories['categoryID'] . '">- ' . htmlspecialchars($categories['category']) . '</span><br>';
193
+        }
194
+
195
+        if (!isset($is_category)) {
196
+            print 'No further categories.';
197
+            die();
198
+        }
199
+    }
200
+}
201
+
202
+### ADDITION DATES ############################################################
203
+
204
+if (isset($_GET['open']) && in_array("dates", $_GET['open'])) {
205
+
206
+    $date_array = array();
207
+    $phpdate_number = array();
208
+    $json = array(
209
+        'mindate' => '',
210
+        'maxdate' => '',
211
+        'datecount' => array()
212
+    );
213
+
214
+    $result = $dbHandle->query("SELECT addition_date,count(*) FROM library $in GROUP BY addition_date ORDER BY addition_date DESC LIMIT 60");
215
+
216
+    while ($fetch = $result->fetch(PDO::FETCH_NUM)) {
217
+        $date_array[] = $fetch[0];
218
+        $phpdate_number[$fetch[0]] = $fetch[1];
219
+    }
220
+
221
+    $dbHandle = null;
222
+
223
+    if (!empty($date_array)) {
224
+        $json['mindate'] = end($date_array);
225
+        $json['maxdate'] = reset($date_array);
226
+        $json['datecount'] = $phpdate_number;
227
+    }
228
+    
229
+    print json_encode($json);
230
+    die();
231
+}
232
+
233
+### AUTHORS ###################################################################
234
+
235
+if (isset($_GET['open']) && in_array("authors", $_GET['open'])) {
236
+
237
+    
238
+    if (isset($_GET['first_letter']) && ctype_alpha($_GET['first_letter'])) {
239
+        $first_letter = $_GET['first_letter'];
240
+    } else {
241
+        $first_letter = 'a';
242
+    }
243
+
244
+    $from = 0;
245
+    if (isset($_GET['from']))
246
+        $from = intval($_GET['from']);
247
+
248
+    $result = $dbHandle->query("SELECT authors FROM library $in");
249
+    $authors = $result->fetchAll(PDO::FETCH_COLUMN);
250
+    $dbHandle = null;
251
+
252
+    $authors_string = '';
253
+    $authors_string = implode(";", $authors);
254
+    $authors = explode(";", $authors_string);
255
+    
256
+    function filter_authors($var) {
257
+        global $first_letter;
258
+        if (!empty($var) && stripos($var, 'L:"'.$first_letter) === 0) {
259
+            return true;
260
+        } elseif (!empty($var) && $first_letter == 'All') {
261
+            return true;
262
+        }
263
+    }
264
+
265
+    $authors = array_filter($authors, 'filter_authors');
266
+
267
+    if (empty($authors)) {
268
+        print '<div>No authors starting with ' . strtoupper($first_letter) . '.</div>';
269
+        die();
270
+    }
271
+
272
+    $authors_array = array_unique($authors);
273
+    usort($authors_array, "strnatcasecmp");
274
+
275
+    $i = 0;
276
+    $isauthor = null;
277
+
278
+    print '<div>';
279
+    
280
+    while (list($key, $authors) = each($authors_array)) {
281
+            if ($i >= $from && $i < ($from + 1000)) {
282
+                $authors = str_replace('L:"', '', $authors);
283
+                $authors = str_replace('",F:"', ', ', $authors);
284
+                $authors = substr($authors, 0, -1);
285
+                print '<span class="author" id="' . urlencode($authors) . '">' . htmlspecialchars($authors) . '</span><br>';
286
+            }
287
+            $i = $i + 1;
288
+            
289
+        if ($i > ($from + 1000))
290
+            break;
291
+    }
292
+
293
+    print '</div>';
294
+}
295
+
296
+### JOURNALS ###################################################################
297
+
298
+if (isset($_GET['open']) && in_array("journal", $_GET['open'])) {
299
+
300
+    $journal_to_browse = array_keys($_GET['open'], 'journal');
301
+
302
+    if (empty($journal_to_browse[0])) {
303
+
304
+        $output = '';
305
+
306
+        $result = $dbHandle->query("SELECT DISTINCT journal FROM library $in ORDER BY journal COLLATE NOCASE ASC");
307
+        $dbHandle = null;
308
+
309
+        while ($fetch = $result->fetch(PDO::FETCH_NUM)) {
310
+
311
+            if (!empty($fetch[0])) {
312
+
313
+                $output .= PHP_EOL . '<div id="' . urlencode($fetch[0]) . '"><span class="jour">'
314
+                        . htmlspecialchars($fetch[0]) . '</span><div style="display:none;margin-left:20px;white-space: nowrap"></div></div>';
315
+            }
316
+        }
317
+
318
+        if (empty($output)) {
319
+            print "No journals.";
320
+            die();
321
+        }
322
+
323
+        print "<div>$output</div>";
324
+    }
325
+
326
+    if (!empty($journal_to_browse[0])) {
327
+
328
+        $output = '';
329
+
330
+        $journal_query = $dbHandle->quote($journal_to_browse[0]);
331
+
332
+        $result = $dbHandle->query("SELECT DISTINCT CAST(year AS DATE) as y FROM library $in $where journal=$journal_query ORDER BY y DESC");
333
+        $dbHandle = null;
334
+
335
+        while ($fetch = $result->fetch(PDO::FETCH_NUM)) {
336
+
337
+            if (!empty($fetch[0])) {
338
+
339
+                $output .= PHP_EOL . '<span class="jour2">' . htmlspecialchars($fetch[0]) . '</span><br>';
340
+            }
341
+        }
342
+
343
+        if (empty($output)) {
344
+            print "No journals.";
345
+            die();
346
+        }
347
+
348
+        print "<div>$output</div>";
349
+    }
350
+}
351
+
352
+
353
+### SECONDARY TITLES ###################################################################
354
+
355
+if (isset($_GET['open']) && in_array("secondary_title", $_GET['open'])) {
356
+
357
+    $secondary_title_to_browse = array_keys($_GET['open'], 'secondary_title');
358
+
359
+    if (empty($secondary_title_to_browse[0])) {
360
+
361
+        $output = '';
362
+
363
+        $result = $dbHandle->query("SELECT DISTINCT secondary_title FROM library $in ORDER BY secondary_title COLLATE NOCASE ASC");
364
+        $dbHandle = null;
365
+
366
+        while ($fetch = $result->fetch(PDO::FETCH_NUM)) {
367
+
368
+            if (!empty($fetch[0])) {
369
+
370
+                $output .= PHP_EOL . '<div id="' . urlencode($fetch[0]) . '"><span class="sec">'
371
+                        . htmlspecialchars($fetch[0]) . '</span><div style="display:none;margin-left:20px;white-space: nowrap"></div></div>';
372
+            }
373
+        }
374
+
375
+        if (empty($output)) {
376
+            print "No secondary titles.";
377
+            die();
378
+        }
379
+
380
+        print "<div>$output</div>";
381
+    }
382
+
383
+    if (!empty($secondary_title_to_browse[0])) {
384
+
385
+        $output = '';
386
+
387
+        $secondary_title_query = $dbHandle->quote($secondary_title_to_browse[0]);
388
+
389
+        $result = $dbHandle->query("SELECT DISTINCT CAST(year AS DATE) as y FROM library $in $where secondary_title=$secondary_title_query ORDER BY y DESC");
390
+        $dbHandle = null;
391
+
392
+        while ($fetch = $result->fetch(PDO::FETCH_NUM)) {
393
+
394
+            if (!empty($fetch[0])) {
395
+
396
+                $output .= PHP_EOL . '<span class="sec2">' . htmlspecialchars($fetch[0]) . '</span><br>';
397
+            }
398
+        }
399
+
400
+        if (empty($output)) {
401
+            print "No secondary titles.";
402
+            die();
403
+        }
404
+
405
+        print "<div>$output</div>";
406
+    }
407
+}
408
+
409
+### TERTIARY TITLES ###################################################################
410
+
411
+if (isset($_GET['open']) && in_array("tertiary_title", $_GET['open'])) {
412
+
413
+    $tertiary_title_to_browse = array_keys($_GET['open'], 'tertiary_title');
414
+
415
+    if (empty($tertiary_title_to_browse[0])) {
416
+
417
+        $output = '';
418
+
419
+        $result = $dbHandle->query("SELECT DISTINCT tertiary_title FROM library $in ORDER BY tertiary_title COLLATE NOCASE ASC");
420
+        $dbHandle = null;
421
+
422
+        while ($fetch = $result->fetch(PDO::FETCH_NUM)) {
423
+
424
+            if (!empty($fetch[0])) {
425
+
426
+                $output .= PHP_EOL . '<div id="' . urlencode($fetch[0]) . '"><span class="sec">'
427
+                        . htmlspecialchars($fetch[0]) . '</span><div style="display:none;margin-left:20px;white-space: nowrap"></div></div>';
428
+            }
429
+        }
430
+
431
+        if (empty($output)) {
432
+            print "No tertiary titles.";
433
+            die();
434
+        }
435
+
436
+        print "<div>$output</div>";
437
+    }
438
+
439
+    if (!empty($tertiary_title_to_browse[0])) {
440
+
441
+        $output = '';
442
+
443
+        $tertiary_title_query = $dbHandle->quote($tertiary_title_to_browse[0]);
444
+
445
+//        $result = $dbHandle->query("SELECT DISTINCT CAST(year AS DATE) as y FROM library $in $where tertiary_title=$tertiary_title_query ORDER BY y DESC");
446
+        $result = $dbHandle->query("SELECT DISTINCT secondary_title FROM library $in $where tertiary_title=$tertiary_title_query ORDER BY secondary_title ASC");
447
+        $dbHandle = null;
448
+
449
+        while ($fetch = $result->fetch(PDO::FETCH_NUM)) {
450
+
451
+            if (!empty($fetch[0])) {
452
+
453
+                $output .= PHP_EOL . '<span class="sec2">' . htmlspecialchars($fetch[0]) . '</span><br>';
454
+            }
455
+        }
456
+
457
+        if (empty($output)) {
458
+            print "No tertiary titles.";
459
+            die();
460
+        }
461
+
462
+        print "<div>$output</div>";
463
+    }
464
+}
465
+
466
+### KEYWORDS ###################################################################
467
+
468
+if (isset($_GET['open']) && in_array("keywords", $_GET['open'])) {
469
+
470
+    $from = 0;
471
+    if (isset($_GET['from']))
472
+        $from = intval($_GET['from']);
473
+
474
+    $result = $dbHandle->query("SELECT keywords FROM library $in");
475
+    $keywords = $result->fetchAll(PDO::FETCH_COLUMN);
476
+
477
+    $keywords_string = '';
478
+    $keywords_string = implode("/", $keywords);
479
+    $keywords = explode("/", $keywords_string);
480
+
481
+    foreach ($keywords as $value) {
482
+        $trimmed_keywords[] = trim($value);
483
+    }
484
+
485
+    $trimmed_keywords = array_filter($trimmed_keywords);
486
+
487
+    $keywords_array = array_unique($trimmed_keywords);
488
+
489
+    if (empty($keywords_array)) {
490
+        print 'No keywords.';
491
+        die();
492
+    }
493
+
494
+    if ($from > count($keywords_array)) {
495
+        print 'No further keywords.';
496
+        die();
497
+    }
498
+
499
+    usort($keywords_array, "strnatcasecmp");
500
+    $keywords_array = array_slice($keywords_array, $from, 1000, true);
501
+
502
+    print '<div>';
503
+
504
+    while (list($key, $keywords) = each($keywords_array)) {
505
+        if (!empty($keywords)) {
506
+            print '<span class="key" id="' . htmlspecialchars(urlencode($keywords)) . '">' . htmlspecialchars($keywords) . '</span><br>';
507
+        }
508
+    }
509
+
510
+    print '</div>';
511
+}
512
+
513
+### SAVED SEARCHES ###################################################################
514
+
515
+if (isset($_GET['open']) && in_array("savedsearch", $_GET['open'])) {
516
+
517
+    $result = $dbHandle->query("SELECT DISTINCT searchname FROM searches WHERE userID=" . intval($_SESSION['user_id']) . " AND searchname LIKE 'advancedsearch#%'");
518
+    $searches = $result->fetchAll(PDO::FETCH_COLUMN);
519
+
520
+    print '<div>';
521
+
522
+    if (!empty($searches)) {
523
+
524
+        foreach ($searches as $search) {
525
+            $search = substr($search, 15);
526
+            print '<div><div class="savedsearch" id="' . rawurlencode($search) . '">' . htmlspecialchars($search) . '</div>';
527
+            print '<button class="rename-search"><i class="fa fa-pencil"></i> Rename</button> <button class="delete-search"><i class="fa fa-trash-o"></i> Delete</button></div>';
528
+        }
529
+    } else {
530
+        print 'No saved searches.';
531
+    }
532
+
533
+    print '</div>';
534
+}
535
+
536
+cache_store();
537
+?>

+ 10
- 0
librarian/ajaxlog.php View File

@@ -0,0 +1,10 @@
1
+<?php
2
+include_once 'data.php';
3
+session_write_close();
4
+
5
+$log = IL_TEMP_PATH . DIRECTORY_SEPARATOR . md5($_GET['user']).'-librarian-import.log';
6
+
7
+if(!file_exists($log) || !is_readable($log)) die();
8
+$string = file_get_contents($log);
9
+die($string);
10
+?>

+ 18
- 0
librarian/ajaxrating.php View File

@@ -0,0 +1,18 @@
1
+<?php
2
+include_once 'data.php';
3
+include_once 'functions.php';
4
+
5
+if(isset($_GET['rating']) && isset($_GET['file'])) {
6
+
7
+	database_connect(IL_DATABASE_PATH, 'library');
8
+
9
+	$query = "UPDATE library SET rating=:rating WHERE id=:id";
10
+
11
+	$stmt = $dbHandle->prepare($query);
12
+
13
+	$stmt->bindParam(':id', $_GET['file']);
14
+	$stmt->bindParam(':rating', $_GET['rating']);
15
+
16
+	$stmt->execute();
17
+}
18
+?>

+ 39
- 0
librarian/ajaxshelf.php View File

@@ -0,0 +1,39 @@
1
+<?php
2
+include_once 'data.php';
3
+include_once 'functions.php';
4
+
5
+if (isset($_GET['file']) && isset($_SESSION['auth'])) {
6
+
7
+    database_connect(IL_DATABASE_PATH, 'library');
8
+
9
+    $user_query = $dbHandle->quote($_SESSION['user_id']);
10
+    $file_query = $dbHandle->quote($_GET['file']);
11
+
12
+    $dbHandle->beginTransaction();
13
+
14
+    $result = $dbHandle->query("SELECT rowid FROM shelves WHERE userID=$user_query AND fileID=$file_query LIMIT 1");
15
+    $relation = $result->fetchColumn();
16
+    $result = null;
17
+
18
+    if (!$relation) {
19
+
20
+        $result = $dbHandle->query("SELECT COUNT(*) FROM library WHERE id=$file_query");
21
+        $exists = $result->fetchColumn();
22
+        $result = null;
23
+        if ($exists == 1) {
24
+            $update = $dbHandle->exec("INSERT OR IGNORE INTO shelves (userID,fileID) VALUES ($user_query,$file_query)");
25
+
26
+            if ($update) echo 'added';
27
+        } else {
28
+            $dbHandle->rollBack();
29
+            echo 'Error! This item does not exist anymore.';
30
+        }
31
+    } else {
32
+        $update = $dbHandle->exec("DELETE FROM shelves WHERE rowid=$relation");
33
+        if ($update)
34
+            echo 'removed';
35
+    }
36
+    
37
+    $dbHandle->commit();
38
+    $dbHandle = null;
39
+}

+ 17
- 0
librarian/ajaxstyles.php View File

@@ -0,0 +1,17 @@
1
+<?php
2
+include_once 'data.php';
3
+include_once 'functions.php';
4
+
5
+$output = array();
6
+
7
+$dbHandle = database_connect(__DIR__, 'styles');
8
+
9
+$title_q = $dbHandle->quote(strtolower('%'. $_GET['term'].'%'));
10
+$result = $dbHandle->query('SELECT title FROM styles WHERE title LIKE ' . $title_q);
11
+$dbHandle = null;
12
+
13
+$titles = $result->fetchAll(PDO::FETCH_COLUMN);
14
+foreach ($titles as $title) {
15
+    $output[] = ucwords($title);
16
+}
17
+echo json_encode($output);

+ 189
- 0
librarian/ajaxsupplement.php View File

@@ -0,0 +1,189 @@
1
+<?php
2
+
3
+//AJAX backend for the supplementary file tab
4
+include_once 'data.php';
5
+include_once 'functions.php';
6
+
7
+$proxy_name = '';
8
+$proxy_port = '';
9
+$proxy_username = '';
10
+$proxy_password = '';
11
+
12
+if (isset($_SESSION['connection']) && ($_SESSION['connection'] == "autodetect" || $_SESSION['connection'] == "url")) {
13
+    if (!empty($_POST['proxystr'])) {
14
+        $proxy_arr = explode(';', $_POST['proxystr']);
15
+        foreach ($proxy_arr as $proxy_str) {
16
+            if (stripos(trim($proxy_str), 'PROXY') === 0) {
17
+                $proxy_str = trim(substr($proxy_str, 6));
18
+                $proxy_name = parse_url($proxy_str, PHP_URL_HOST);
19
+                $proxy_port = parse_url($proxy_str, PHP_URL_PORT);
20
+                $proxy_username = parse_url($proxy_str, PHP_URL_USER);
21
+                $proxy_password = parse_url($proxy_str, PHP_URL_PASS);
22
+                break;
23
+            }
24
+        }
25
+    }
26
+} elseif (isset($_SESSION['connection']) && $_SESSION['connection'] == "proxy") {
27
+    if (isset($_SESSION['proxy_name']))
28
+        $proxy_name = $_SESSION['proxy_name'];
29
+    if (isset($_SESSION['proxy_port']))
30
+        $proxy_port = $_SESSION['proxy_port'];
31
+    if (isset($_SESSION['proxy_username']))
32
+        $proxy_username = $_SESSION['proxy_username'];
33
+    if (isset($_SESSION['proxy_password']))
34
+        $proxy_password = $_SESSION['proxy_password'];
35
+}
36
+
37
+session_write_close();
38
+
39
+$error = null;
40
+if (isset($_POST['filename']) && preg_match('/[^a-zA-Z0-9\.]/', $_POST['filename']) > 0)
41
+    $error = 'Invalid request.';
42
+
43
+##########	remove supplementary files	##########
44
+
45
+if (!empty($_GET['files_to_delete'])) {
46
+
47
+    while (list($key, $supplementary_file) = each($_GET['files_to_delete'])) {
48
+
49
+        $supplementary_file = preg_replace('/[\/\\\]/', '_', $supplementary_file);
50
+        if (is_file(IL_SUPPLEMENT_PATH . DIRECTORY_SEPARATOR . get_subfolder($supplementary_file) . DIRECTORY_SEPARATOR . $supplementary_file))
51
+            unlink(IL_SUPPLEMENT_PATH . DIRECTORY_SEPARATOR . get_subfolder($supplementary_file) . DIRECTORY_SEPARATOR . $supplementary_file);
52
+    }
53
+}
54
+
55
+##########	rename supplementary files	##########
56
+
57
+if (!empty($_POST['rename']) && !empty($_POST['file'])) {
58
+
59
+    while (list($old_name, $new_name) = each($_POST['rename'])) {
60
+
61
+        $old_name = preg_replace('/[\/\\\]/', '_', $old_name);
62
+
63
+        if (is_writable(IL_SUPPLEMENT_PATH . DIRECTORY_SEPARATOR . get_subfolder($old_name) . DIRECTORY_SEPARATOR . $old_name) && !empty($new_name)) {
64
+
65
+            $new_name = preg_replace('/[\/\\\]/', '_', $new_name);
66
+            $new_name = preg_replace('/[^a-zA-Z0-9\-\_\.]/', '_', $new_name);
67
+            $new_name = substr($old_name, 0, 5) . $new_name;
68
+            if ($old_name != $new_name)
69
+                $rename = rename(IL_SUPPLEMENT_PATH . DIRECTORY_SEPARATOR . get_subfolder($old_name) . DIRECTORY_SEPARATOR . $old_name, IL_SUPPLEMENT_PATH . DIRECTORY_SEPARATOR . get_subfolder($new_name) . DIRECTORY_SEPARATOR . $new_name);
70
+        }
71
+    }